字频程序中的内存泄漏

时间:2016-05-01 03:38:24

标签: c memory-leaks

我在写作的wf函数中泄漏了很少的内存,而我似乎无法准确找到它。我使用哈希表来保持频率,但我的测试使它看起来不像哈希函数。这是我打开/读取文件和最后释放数据的功能。我确定这是一个简单的错误,但是我一直在查看这段代码太长时间无法看到它。

typedef struct {
   int noInFiles, numFiles, numToPrint;
   char** fileNames;
   FILE** files;
   Hash hash;
} Freq;

void handleInput(int argc, char* argv[], Freq* freq) {
   int num = 0, i, j = 0;
   char* crap;

   printf("memcurrent pre fileName alloc: %d\n\n", memCurrent());
   freq->fileNames = calloc(argc - 1, sizeof(char**));
   printf("memcurrent post filename alloc: %d\n\n", memCurrent());
   freq->numToPrint = 10;

   if(argc < 2) {
      freq->noInFiles = 1;
      freq->numFiles = 0;
      return;
   }

   for(i = 1; i < argc; i++) {
      if(argv[i][0] == '-') {
         if(argv[i][1] == 'n') {
            num = strtol(argv[i] + 2, &crap, 10);
            freq->numToPrint = num;
         }
         else {
            fprintf(stderr, "Usage: wf [-nX] [file...]\n");
            exit(EXIT_FAILURE);
         }
      }
      else {
         freq->fileNames[j] = calloc(strlen(argv[i]) + 1 ,sizeof(char));
         strcpy(freq->fileNames[j], argv[i]);
         j++;
         freq->numFiles++;
      }
   }
}

void openFiles(Freq* freq) {
   int i;
   char* str;

   printf("Memcurrent pre open: %d\n",memCurrent());
   freq->files = calloc(freq->numFiles,sizeof(FILE**));
   printf("Memcurrent post open: %d\n",memCurrent());

   for(i = 0; i < freq-> numFiles; i++) {
      freq->files[i] = fopen(freq->fileNames[i],"r");
      if(freq->files[i] == NULL) {
         str = malloc(strlen(freq->fileNames[i]) + 5);
         sprintf(str,"wf: %s",freq->fileNames[i]);
         perror(str);
         free(str);
         exit(EXIT_FAILURE);
      }
   }
}

void freeFreq(int argc, Freq* freq) {
   int i;

   for(i = 0; i < argc - 1 ; i++) {
      free(freq->fileNames[i]);
   }
   free(freq->fileNames);
   free(freq->files);
}

哈希函数

typedef struct {
   Entry* arr;
   int size, numValid;
} Hash;

void initHash(Hash* hash) {
   hash->arr = calloc(BASESIZE, sizeof(Entry));
   TOTALALLOC =+ (BASESIZE * sizeof(Entry));
   hash->size = BASESIZE;
   hash->numValid = 0;
}

void freeTable(Hash* hash) {
   int i;
   for(i = 0; i < hash->numValid - 1; i++) {
      if(hash->arr[i].correct == 1 && hash->arr[i].valid == 1) {
         wordsFreed++;
         free(hash->arr[i].word);
      }
   }
   free(hash->arr);
}

2 个答案:

答案 0 :(得分:2)

可能是这样:

for(i = 0; i < hash->numValid - 1; i++) {

如果你在启动时将numValid设置为0,我假设你每次向数组添加一个条目时都会增加它。

因此,如果numValid为1,那么您将永远不会循环,这意味着您将泄漏其中一个条目。似乎每次释放哈希时,都会泄漏一个条目,除非哈希根本没有条目。

答案 1 :(得分:1)

这可能无法解决您的问题,但是..

freq->fileNames的分配数量和解除分配数之间存在不匹配。

分配:

  else {
     freq->fileNames[j] = calloc(strlen(argv[i]) + 1 ,sizeof(char));
     strcpy(freq->fileNames[j], argv[i]);
     j++;
     freq->numFiles++;
  }

取消分配:

for(i = 0; i < argc - 1 ; i++) {
   free(freq->fileNames[i]);
}

假设分配逻辑正确,解除分配的逻辑必须是:

for(i = 0; i < freq->numFiles ; i++) {
   free(freq->fileNames[i]);
}

<强> PS

我注意到您已拨打fopen,但未在发布的代码中拨打fclose