交换功能出现分段故障
segmentation fault in swap function
我正忙着写一行学习用的代码。这个作业我已经做了很多了,但我总是遇到同样的问题。在交换功能上,当输入字符时,我一直遇到分段错误(word &不在主"字典"字符串中的Word2)。有人能告诉我是什么原因导致了这个问题,我该如何解决它吗?对不起,如果有什么不清楚,我刚刚开始学习c++。
出现分段错误的代码:
void swapWords(char **dict, char *word, char *word2)
{
int i;
int d;
int x;
int y;
char *tmp;
while (1){
for(i = 0; i < MAX_NUMBER_OF_WORDS; i++)
{
if(strcmp(word, dict[i]) != 0)
{
if(i == MAX_NUMBER_OF_WORDS -1)
{
printf("Cannot swap words. Atleast one word missing in the dictionary.n");
goto error;
}
}
else
{
x = i;
break;
}
}
for(d = 0; d < MAX_NUMBER_OF_WORDS; d++)
{
if(strcmp(word2, dict[d]) != 0)
{
if(d == MAX_NUMBER_OF_WORDS -1)
{
printf("Cannot swap words. Atleast one word missing in the dictionary.n");
goto error;
}
}
else
{
y = d;
break;
}
}
tmp = dict[x];
dict[x] = dict[y];
dict[y] = tmp;
error: break;
}
}
整个代码:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#define MAX_NUMBER_OF_WORDS 10
void swapWords(char **dict, char *word, char *word2)
{
int i;
int d;
int x;
int y;
char *tmp;
while (1){
for(i = 0; i < MAX_NUMBER_OF_WORDS; i++)
{
if(strcmp(word, dict[i]) != 0)
{
if(i == MAX_NUMBER_OF_WORDS -1)
{
printf("Cannot swap words. Atleast one word missing in the dictionary.n");
goto error;
}
}
else
{
x = i;
break;
}
}
for(d = 0; d < MAX_NUMBER_OF_WORDS; d++)
{
if(strcmp(word2, dict[d]) != 0)
{
if(d == MAX_NUMBER_OF_WORDS -1)
{
printf("Cannot swap words. Atleast one word missing in the dictionary.n");
goto error;
}
}
else
{
y = d;
break;
}
}
tmp = dict[x];
dict[x] = dict[y];
dict[y] = tmp;
error: break;
}
}
void removeWord(char **dict, char *word)
{
int i;
int d;
for(i = 0; i < MAX_NUMBER_OF_WORDS; i++)
{
if(strcmp(dict[i], word) == 0)
{ dict[i] = NULL;
for(d = i+1; d < MAX_NUMBER_OF_WORDS; d++)
{ if(dict[d] == NULL)
{ dict[i] = dict[d-1];
dict[d-1] = NULL;
break;
}
}
break;
}
}
}
void printDict(char **dict)
{
int i = 0;
if(dict[0] == NULL)
{
printf("The dictionary is empty.n");
}
else{
while (dict[i] != NULL)
{
printf("- %sn", dict[i]);
i++;
}
}
}
void addWord(char **dict, char *word)
{
int d;
char *word1;
for(d = 0; d < MAX_NUMBER_OF_WORDS; d++)
{
if (dict[d] == NULL)
{
word1 = (char*) malloc(sizeof(char)*(strlen(word) + 1));
strcpy(word1, word);
dict[d] = word1;
break;
}
}
}
int numberOfWordsInDict(char **dict)
{
int i = 0;
int d;
for (d = 0; d < MAX_NUMBER_OF_WORDS; d++){
if(dict[d] != NULL)
{
i++;
}
}
return i;
}
int main()
{
char *dict[MAX_NUMBER_OF_WORDS] = {};
char word[36];
char word2[36];
char c;
int i;
while(printf("Command (a/p/r/s/q): "))
{
scanf(" %c", &c);
switch (c){
case 'p': printDict(dict);
break;
case 'a': printf("Enter a word: ");
scanf("%s", word);
addWord(dict, word);
break;
case 'n': i = numberOfWordsInDict(dict);
printf("%dn", i);
break;
case 'r': printf("Remove a word: ");
scanf("%s", word);
removeWord(dict, word);
break;
case 's': printf("Swap two words:n");
printf("Enter first word: ");
scanf("%s", word);
printf("Enter second word: ");
scanf("%s", word2);
swapWords(dict, word, word2);
break;
case 'q': return 0;
}
}
}
尽管马可和π α ντα ρ ε ν可能是对的,但如果你自己发现实际的错误,对你作为学生的学习将是最有帮助的。然而,这里有一些事情需要考虑,因为这绝对不会是你作为程序员的最后一个段错误问题(仅这个月我就遇到了至少20个)。
段错误几乎总是由试图修改或读取它没有读取或修改权限的内存的代码引起的。当程序启动时,会给它一块内存(RAM)供它使用。出于安全原因,不允许任何程序使用该块之外的内存。还有其他限制因素在起作用。
作为一般规则,如果您试图读取超过数组末尾的内存,那么您有很高的风险获得段错误,或者在其他情况下,数据乱码。关于这一点的官方这个词实际上来自C, c++的父语言,因为访问数组的末尾会导致"未定义行为"。或者,正如USENET上曾经说过的那样,"编译器让恶魔从你鼻子里飞出来是合法的"。这种行为是完全不可预测的。值得庆幸的是,这种未定义的行为通常是段错误。
顺便说一下,如果您试图访问未初始化的 数组,也会发生类似的奇怪情况。NOW,由于您通过循环访问数组的元素,另一个可能的原因是您的循环继续超出了您认为的位置。有时,修改代码使循环的迭代器(在您的示例中是i
)在每次迭代中打印出来是有帮助的。这可以帮助您发现循环是否超出了应有的范围。
总之,check…
- 在我尝试读或写之前,我是否初始化了所有的数组他们吗?
- 我的循环是否在我预期的地方开始和停止?检查"off-by- 1"错误(即从1开始而不是0),无限循环(忘记自增迭代器或停止条件是)
- 我是否试图读取/写入超过数组的末尾?
- 如果我正在使用c字符串,我忘记了NULL终止符吗?
除了调试器(您应该学习如何使用它)之外,像valgrind这样的工具在查找内存错误的原因方面也很有用。通常,它可以指向发生段错误的代码行。
我自己发现了问题出在字符串上。我知道自己找出问题是最好的学习方式,我也试过了,但我就是弄不明白为什么它会返回segfault。由于这是我的第五次赋值,我只是刚刚了解数组和指针是如何工作的。我假设数组已经初始化为'NULL',正如我已经在addWord函数中将指针与'NULL'进行比较。当然,我认为这是非常愚蠢的。我可能没有自己解决这个问题,但它仍然是我不会再忘记的事情。
最有可能的分割错误发生在这里:
if(strcmp(word, dict[i]) != 0)
事实上,很有可能i>变得比你的字典的大小更大,如果你的字典有3个元素,你试图访问第4个,你正在访问一个未知的区域或ram,这会导致分割错误。解决方案是确保你的for循环在字典的最后一个元素处停止,上面的评论中提出了π
- 分段故障(堆芯转储)矢量
- 数组的指针从不分段故障
- Windows 10-使用gtkmm-3.0库和g++[包括再现]的分段故障
- 分段故障 运行C++代码时出现 SIGSEGV
- 分段故障背包问题
- 分段故障 11,从类函数显示动态 C 字符串
- 面临分段故障 使用 ffmpeg 读取视频时,因为"pFormatCtx-> streams [i]-> codecpar"的地址0x00
- 在C++中,当指向删除和指向不同对象时,分段故障指针
- 分段故障说明
- 分段故障(核心转储)-不知道为什么
- 分段故障线程
- hiredis SET遇到分段故障
- 分段故障,合并排序算法
- 多线程程序中的分段故障和gdb回溯上的不完整信息
- 到达主C++之前分段故障
- 分段故障核心使用 IF流转储
- 使用向量的移动键盘排列(分段故障)
- 在二进制树插入和遍历期间,我得到了分段故障
- 分段故障在类之间返回整数
- C++分段故障BST