Search code examples
clinuxsegmentation-faultvalgrindfree

Address 0x0 is not stack'd, malloc'd or (recently) free'd in C


i'm developing a program that should read line from a file and retrieve information manipulating them. The file in question is:

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

I use this method:

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);
    }
}

I pass to this method the parameters as input argunents. The variable word store to word to search, file store the path of the file to open (in this case, the file showed above) and fileToCheck is the file path to be searched inside the file (the one immediately after FILE).

I can pass every string i want as input arguments in the variable word except of abc. Only if i pass abc i get: (valgrind running)

==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)

I don't get why this happen only in i pass abc as arguments. In the main method i only call this function, nothing else:

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

      return 0;
}

The running command is :

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

I know that Is caused by a null pointer in line 414, but why i pass 'ac' it works and not with 'abc'?


Solution

  • To solve the problem i added a control in the three if at the bottom:

    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;
               }
         }         
    }
    

    And also i changed these portion of code:

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

    With these more performant lines:

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