C 删除未使用的变量会导致崩溃
我的函数中有一个未使用的变量。如果我删除它,程序就会崩溃。我很难理解为什么。我认为这是因为我正在访问dataArr的边界之外 关于定义: userFile是要读取的argv输入文本文件 dataArr是该文本文件的行,存储在字符串数组中。 n[80]是以前使用的指针数组,用于存储单个值(将其写入另一个函数) strdup复制字符串(非标准库) 如果有帮助,将n[80]的值切换到n[20]会产生错误,但n[21]不会C 删除未使用的变量会导致崩溃,c,C,我的函数中有一个未使用的变量。如果我删除它,程序就会崩溃。我很难理解为什么。我认为这是因为我正在访问dataArr的边界之外 关于定义: userFile是要读取的argv输入文本文件 dataArr是该文本文件的行,存储在字符串数组中。 n[80]是以前使用的指针数组,用于存储单个值(将其写入另一个函数) strdup复制字符串(非标准库) 如果有帮助,将n[80]的值切换到n[20]会产生错误,但n[21]不会 char ** read_file(char * userFile) {
char ** read_file(char * userFile)
{
char * n[80]; // DO NOT REMOVE THIS LINE UNDER ANY CIRCUMSTANCES. IT IS BLACK VOODOO MAGIC.
char currLine[256];
char * dataArr[80];
char * eof;
int lineCount = 0;
int i = 0;
int j = 0;
FILE * fp;
fp = fopen(userFile, "r");
while((eof = fgets(currLine, sizeof(currLine), fp)) != NULL)
/* Stores the file into an array */
{
if (fp == NULL)
{
fprintf(stderr, "Can't open input file in.list!\n");
exit(1);
}
dataArr[i] = strdup(eof);
i++;
}
return dataArr;
}
编辑:
我使用
dataArr = read_file(argv[1]);
我有一个坏习惯,就是对函数使用相同的变量名。这是因为数组分配内存并修改程序的存储方式 当您执行以下操作时,会导致未定义的行为:
return dataArr;
由于此数组是局部变量:
因此,当函数终止时,它将超出范围。这意味着,当调用方尝试使用它时,它很可能已超出范围
顺便说一下,您首先读取文件,然后检查它是否已打开。您应该这样做:
fp = fopen(userFile, "r");
if (fp == NULL)
{
fprintf(stderr, "Can't open input file in.list!\n");
exit(1);
}
while((eof = fgets(currLine, sizeof(currLine), fp)) != NULL) {
...
这一行:
return dataArr;
将导致未定义的行为,这是您可能面临的最严重问题之一。这一情况如此糟糕的原因是,通常很难准确定位。UD经常以这种奇怪的方式表现出来
这与char*n[80]完全无关
简言之,UD意味着任何事情都可能发生。有关更多信息,请参阅此链接:程序究竟在哪里崩溃?每当我尝试调用该函数时,它都会挂起。几秒钟后,它返回:
char*dataArr[80]。。。。。返回数据arr代码>这是一个局部变量,离开函数后无效。返回该数组的地址会带来很多麻烦。这是黑色巫术。不,这是由于返回局部变量的地址而导致的未定义行为。如果(fp==NULL)
在使用它进行读取后检查NULL
。捕捉良好。我记得不久前更改了它,然后在ctrl+z的疯狂操作中丢失了该修订。将变量char*dataArr[80]更改为static char*dataArr[80]是否是一种好的做法?“[…]不久前更改了它,然后在ctrl+z狂欢中丢失了该修订。”-您应该开始使用:-)No@AlexWittwer。您需要动态分配阵列(请参阅my)。这样,即使函数终止,数组也将有效。只有当您取消分配内存时,它才会超出范围。顺便说一下,你必须释放内存,别忘了。你说的“git”是什么意思?@AlexWittwer是最常用的版本控制系统。保存源代码的版本有助于防止ctrl-z sprees造成的损坏。如果您的代码变得无法识别,只需回滚到以前的版本:)
return dataArr;