C 删除未使用的变量会导致崩溃

C 删除未使用的变量会导致崩溃,c,C,我的函数中有一个未使用的变量。如果我删除它,程序就会崩溃。我很难理解为什么。我认为这是因为我正在访问dataArr的边界之外 关于定义: userFile是要读取的argv输入文本文件 dataArr是该文本文件的行,存储在字符串数组中。 n[80]是以前使用的指针数组,用于存储单个值(将其写入另一个函数) strdup复制字符串(非标准库) 如果有帮助,将n[80]的值切换到n[20]会产生错误,但n[21]不会 char ** read_file(char * userFile) {

我的函数中有一个未使用的变量。如果我删除它,程序就会崩溃。我很难理解为什么。我认为这是因为我正在访问dataArr的边界之外

关于定义: userFile是要读取的argv输入文本文件 dataArr是该文本文件的行,存储在字符串数组中。 n[80]是以前使用的指针数组,用于存储单个值(将其写入另一个函数) strdup复制字符串(非标准库)

如果有帮助,将n[80]的值切换到n[20]会产生错误,但n[21]不会

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;