【问题标题】:Address 0x0 is not stack'd, malloc'd or (recently) free'd in C地址 0x0 在 C 中没有被堆栈、malloc 或(最近)释放
【发布时间】:2020-04-07 10:06:27
【问题描述】:

我正在开发一个程序,它应该从文件中读取行并检索操作它们的信息。有问题的文件是:

WORD abc
TOTAL 10
FILE /home/user/Scrivania/find/try
OCCURRENCES 2
0 0
1 0
FILE /home/user/Scrivania/find/try1
OCCURRENCES 2
3 0
4 0
FILE /home/user/Scrivania/prova/prova1/prova3/try3
OCCURRENCES 3
2 0
3 0
4 0
FILE /home/user/Scrivania/prova/try4
OCCURRENCES 3
2 0
3 0
4 0
WORD ac
TOTAL 10
FILE /home/user/Scrivania/find/try
OCCURRENCES 3
2 0
3 0
4 0
FILE /home/user/Scrivania/find/try1
OCCURRENCES 3
0 0
1 0
2 0
FILE /home/user/Scrivania/prova/prova1/prova3/try3
OCCURRENCES 2
0 0
10
FILE /home/user/Scrivania/prova/try4
OCCURRENCES 2
0 0
1 0

我用这个方法:

void getWordOccurences(char *word, char *file, char *fileToCheck){
    FILE *f;
    char *curr = NULL;
    size_t len = 0;
    ssize_t line_size;
    char *currentWord = NULL;
    char *currentFile = NULL;
    char *p = NULL;
    int check = 0;

    if(fileToCheck == NULL){
        printf("Pass a file as arguments\r\n");
    }else{
        f = fopen(file, "r");
        if(f == NULL){
            fprintf(stderr, "Cannot open %s, exiting. . .\n", file);
            exit(1);
        }
        while((line_size = getline(&curr, &len, f)) != -1){
            trimTrailing(curr);
            if(curr[0] == 'W'){
                currentWord = (char*)malloc((strlen(curr)+1)*sizeof(char));
                strcpy(currentWord, strchr(curr, ' '));
                currentWord++;
                continue;
            }
            if(curr[0] == 'F'){
                currentFile = (char*)malloc((strlen(curr)+1)*sizeof(char));
                strcpy(currentFile, strchr(curr, ' '));
                currentFile++;
                continue;
            }
            if(curr[0] == 'O'){
                p = (char*)malloc((strlen(curr)+1)*sizeof(char));
                strcpy(p, strchr(curr, ' '));
                p++;
                continue;
            }
            if(strcmp(currentWord, word) == 0){
                if(strcmp(currentFile, fileToCheck) == 0){ // LINE 414
                    if(atoi(p) > 0){
                        check = 1;
                        printf("%s \n", curr);
                        continue;
                    }
                }         
            }
        }

        if(check == 0){
            printf("The word %s doesn't occur in the file %s \n", word, fileToCheck);
        }
        fclose(f);
    }
}

我将参数作为输入参数传递给此方法。变量word 存储到要搜索的单词,file 存储要打开的文件的路径(在这种情况下,如上所示的文件),fileToCheck 是要在文件中搜索的文件路径(立即在FILE之后)。

我可以在变量word 中传递我想要的每个字符串作为输入参数,abc 除外。只有当我通过abc 我得到:(valgrind 运行)

==2447== Invalid read of size 1
==2447==    at 0x4FA5D60: __strcmp_ssse3 (strcmp.S:144)
==2447==    by 0x10A21D: getWordOccurences (find.c:414)
==2447==    by 0x108F3E: main (find.c:44)
==2447==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
Segmentation fault (core dumped)

我不明白为什么只有在我将abc 作为参数传递时才会发生这种情况。 在 main 方法中我只调用了这个函数,没有别的:

int main(int argc, char * argv[]){
      getWordOccurences(argv[1], argv[2], argv[3]);

      return 0;
}

运行命令是:

valgrind myprog abc inputFile /home/users/Scrivania/find/try

我知道这是由第 414 行中的空指针引起的,但为什么我传递 'ac' 它可以工作而不是 'abc'?

【问题讨论】:

  • currentWord++; currentFile++; p++; 这些行应该做什么?
  • 我不明白程序要完成什么。
  • 你不能strcmp一个空指针。
  • Valgrind 指出您正在尝试从地址 0x0(又名 NULL)读取 1 个字节,这是行不通的......所以currentFile 或 @ 987654341@ 是NULL 在线414...(很可能是currentFile
  • 我不会也不会。我会寻找WORD 公告,一旦找到,分配空间来保存该行的其余部分,然后使用sscanf%s 来啜饮单词令牌,并忽略前导和尾随空格(因为这就是@ 987654348@ 会自动执行)。无论如何,请考虑一下您为此努力所需的状态,以及可以/应该忽略什么或触发状态更改。这确实是您在编写一行代码之前应该关注的地方。

标签: c linux segmentation-fault valgrind free


【解决方案1】:

为了解决这个问题,我在底部的三个 if 中添加了一个控件:

if(currentWord != NULL && (strcmp(currentWord, word) == 0)){
     if(currentFile != NULL && (strcmp(currentFile, fileToCheck) == 0)){
          if(p != NULL && (atoi(p) > 0)){
                check = 1;
                printf("%s \n", curr);
                continue;
           }
     }         
}

我还更改了这部分代码:

strcpy(currentWord, strchr(curr, ' '));
currentWord++;

strcpy(currentFile, strchr(curr, ' '));
currentFile++;

strcpy(p, strchr(curr, ' '));
p++;

有了这些更高效的行:

sscanf(strchr(curr, ' '), "%s", currentWord);
sscanf(strchr(curr, ' '), "%s", currentFile);
sscanf(strchr(curr, ' '), "%s", p);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-23
    • 1970-01-01
    • 2017-09-13
    • 2018-10-12
    • 1970-01-01
    • 2019-08-21
    • 1970-01-01
    相关资源
    最近更新 更多