代码之家  ›  专栏  ›  技术社区  ›  Stelios Papamichail

使用char时双重释放或损坏**

  •  1
  • Stelios Papamichail  · 技术社区  · 6 年前

    我正在为我的 int *occurrences int *wordCounts char **uniqueWords 指针,然后在分配内存的函数末尾,释放它们。但是,当我编译程序时,我得到一个 double free or corruption (!prev) aborting 错误。它是由 malloc , free 或者可能是由于我如何在 for loop ?

    附言:我说的是 sortedCount() 方法,位于末端

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <math.h>
    
    #define MAX_STRING_SIZE 512 /* each line in the file can have up to 512 chars */
    
    void populateWordsArray(int); 
    void reverse(int);
    void first(int);
    void middle(int);
    void last(int);
    int count(int, char*, int);
    void sortedCount(int);
    void determineUniqueWords(int *,char **, int);
    void *malloc_or_end(size_t);
    
    void* malloc_or_end(size_t sz) {
      void *pointer;
      pointer = malloc(sz);
      if(pointer == NULL) {
        printf("Out of memory, terminating.\n");
        exit(-1);
      }
      return pointer;
    }
    
    /* turn into local */
    FILE *file; 
    char **wordList; 
    
    void determineUniqueWords(int *occurrences, char **word, int N) {
        int i = 0;
        int j = 0;
        for(i = 0; i < N; i++) {
    
            if(occurrences[i] < 1) {
                continue;
            }
    
            for(j = i + 1; j < N; j++) {
                if(occurrences[j] == 1 && (strcmp(word[i],word[j])) == 0) {
                    occurrences[i]++;
                    occurrences[j] = 0;
                }
            }
        }
    }
    
    /**
     * Function populateWordsArray: reads N words from
     * the given file and populates the wordList array with them.
     * Has one argument: int N - the number of words to read. 
     * */
    void populateWordsArray(int N) {
        int i = 0;
    
        while(i < N && (fscanf(file,"%s",wordList[i]) == 1)) { /* fscanf returns the number of successfully read items. If it's not 1, the read failed. Same as checking if fscanf reads the eof char. */
            i++;
        }
    }
    
    /**
     * Function reverse: prints the words of the
     * text file in reverse order.
     * */
    void reverse(int N) {
        int i = 0;
        for(i = N-1; i >= 0; i--) {
            if(i == 0) {
                printf("%s \n",wordList[i]);
            } else if(strcmp(wordList[i],"") == 0) { /* improve this in main-> memory allocation */
                continue;
            }else {
                printf("%s ",wordList[i]);
            }
        }
        return;
    }
    
    /**
     * Function first: Prints the first char of each
     * word in the file.
     * */
    void first(int N) {
        char firstChar;
        int i = 0;
    
        for(i = 0; i < N; i++) {
            firstChar = *wordList[i];
            printf("%c",firstChar);
        }
        printf("\n");
        return;
    }
    
    /**
     * Function middle: Prints the middle char of each word
     * from the given file.
     * */
    void middle(int N) {
        int middleIndex = 0;
        int i = 0;
        char midChar;
    
        for(i = 0; i < N; i++) {
            if((strlen(wordList[i]) % 2) == 0) { /* artios */
                middleIndex = ((strlen(wordList[i]) / 2) - 1);
                midChar = wordList[i][middleIndex];
            }
            else { /* peritos */
                middleIndex = (int) ceil((strlen(wordList[i]) / 2));
                midChar = wordList[i][middleIndex];
            }
            printf("%c",midChar);
        }
        printf("\n");
        return;
    }
    
    /**
     * Function last: Prints the last char of each
     * word from the given file.
     * */
    void last(int N) {
        int i = 0;
        char lastChar;
        int lastPos;
    
        for(i = 0; i < N; i++) {
            lastPos = strlen(wordList[i]) - 1;
            lastChar = wordList[i][lastPos];
            printf("%c",lastChar);
        }
        printf("\n");
        return;
    }
    
    /**
     * Function count: Prints the number of times
     * that the selected word is found inside the N first words
     * of the file.
     * */
    int count(int N, char *word, int callID) {
        int i = 0;
        int count = 0;
        for(i = 0; i < N; i++) {
            if(strcmp(word,wordList[i]) == 0) {
                count++;
            }
        }
        if(callID == 0) { /* if callID == 0 (main called count and we want the output) */
            printf("%d",count);
            printf("\n");
        }
        return count;
    }
    
    void sortedCount(int N) {
        int i,j = 0;
        int *occurrences;
        int *wordCounts;
        char **uniqueWords;
    
        /* mem allocation */
        uniqueWords = malloc_or_end(N * sizeof(char*)); /* worst case: every word is unique */
        wordCounts = malloc_or_end(N * sizeof(int));
        occurrences = malloc_or_end(N * sizeof(int));
    
        /* initialize rootWord and occurrences for the "each word is unique and occurs only once" scenario */
        for(i = 0; i < N; i++) {
            uniqueWords[i] = malloc_or_end(MAX_STRING_SIZE * sizeof(char));
            occurrences[i] = 1;
        }
    
        determineUniqueWords(occurrences,wordList,N);
    
        /* populate the wordCounts & uniqueWords "arrays" with the appropriate data in order to sort them successfully */
        for(i = 0; i < N; i++) {
            if(occurrences[i] > 0) {
                wordCounts[i] = count(N,wordList[i],1);
                uniqueWords[i] = wordList[i];
            }
        }
    
        for(i = 0; i < N; i++) {
            free(uniqueWords[i]);
        }
        free(uniqueWords);
        free(occurrences);
        free(wordCounts);
        return;
    }
    
    int main(int argc,char *argv[]) { /* argv[1] = op argv[2] = name argv[3] = <word> */
        int N = -1;
        int i = 0;
        int spaceNum,nlNum = -1;
    
    
        file = fopen(argv[2],"r");
    
        if(file == (FILE *) NULL) { /* check if the file opened successfully */
            fprintf(stderr,"Cannot open file\n");
        }
    
        fscanf(file,"%d",&N); /* get the N number */
    
        wordList = malloc_or_end(N * sizeof(char *)); /* allocate memory for pointers */
    
        for(i = 0; i < N; i++) {
            wordList[i] = malloc_or_end(MAX_STRING_SIZE * sizeof(char)); /* allocate memory for strings */
        }
    
        populateWordsArray(N);
    
        if(strcmp(argv[1],"-reverse") == 0) {
            reverse(N);
        } else if(strcmp(argv[1],"-first") == 0) {
            first(N);
        } else if(strcmp(argv[1],"-middle") == 0) {
            middle(N);
        } else if(strcmp(argv[1],"-last") == 0) {
            last(N);
        } else if((strcmp(argv[1],"-count") == 0) && argv[3] != NULL) {
            i = count(N,argv[3],0);
        } else if((strcmp(argv[1],"-sorted") == 0) && (strcmp(argv[3],"-count") == 0)) {
            sortedCount(N);
        } else {
            /* i only wish i could print something here */
        }
    
    
        /* End of program operations */
        for(i = 0; i < N; i++) {
            free(wordList[i]);
        }
        free(wordList);
        fclose(file);
        return 0;
    }
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Govind Parmar vitaly.v.ch    6 年前

    您正在覆盖第185行中指向堆内存的指针的值:

    uniqueWords[i] = wordList[i];
    

    这意味着当你 free 稍后,您将实际释放 wordList . 现在有两个问题:

    1. 当你释放 词表 在244-246行,它将是一个双自由
    2. 你失去了对 uniqueWords 排。

    使用 strcpy 分配给动态分配的字符串,而不是 = 操作。