首页 文章

释放为c中的struct数组分配的内存

提问于
浏览
-2

我有一个关于释放我为c中的struct数组分配的内存的问题 .

我已经搜索了已发布的问题,没有任何内容可以澄清我的问题 .

首先,我事先创造了几个结构; struct中的变量都是固定大小的,例如 char str[250]int .

我创建了几个struct指针,并使用malloc将其转换为struct数组 .

但是当我试图释放这些结构数组时,由于某些原因它不会释放 .

当我通过valgrind检查内存泄漏时,它告诉我,我无法释放内存,我肯定会丢失这些struct数组的内存 .

以下是与我的结构类似的一段代码;我的malloc数组上的malloc方法;和我的自由记忆的方法 .

struct word{
  char word[250];
  int occurrence; };

struct same_word{
  char word[250];};

int main(int argc, char** agrv){
    FILE* fp;
    fp = fopen(argv[1],"r");
    if(fp == NULL)
    {
         perror("File does not open.");
         exit(0);
    }

    int total_number_of_word = /*number of word I have in my txt file*/
    int total_number_of_same_word = /*number of same word I have in my txt file*/
    /* Assuming I knew these two numbers in advance*/

    struct word* essay = malloc(total_number_of_word * sizeof(struct word));
    struct same_word* unique_word = malloc(total_number_of_same_word * sizeof(struct same_word));

    int index = 0;
    int index2 = 0;
    int ret = 0;
    while(index < total_number_of_word){
          fscanf(fp,"%s",essay[index].word);
          essay[index].occurrence = 1;
          ret = strcmp(essay[index].word,"Hello");
          if( ret == 0)
          {
               strcpy(unique_word[index2].word,essay[index].word);
               index2++;
          }
          index++;
    }
    free(essay);
    free(unique_word);
    fclose(fp);

}

提前致谢 .

P.S感谢所有在我的问题中指出错误的人 .

2 回答

  • 0

    只需对代码进行最少的更改:

    • agrv 已更改为 argv .

    • 在使用 argv[1] 之前测试 argc ,退出并报告失败 .

    • 来自 scanf() 的测试结果,当它不是 1 时退出 .

    • 将单词数设置为1000 .

    • 断言内存分配成功(同样使用 #include <assert.h> ) .

    • 关闭文件 .

    • 在末尾添加返回0 .

    代码编译并在Mac OS X 10.11.4 El Capitan上的 valgrind 下干净利落地运行 .

    #include <assert.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    struct word
    {
        char word[250];
        int occurrence;
    };
    
    struct same_word
    {
        char word[250];
    };
    
    int main(int argc, char **argv)
    {
        if (argc != 2)
        {
            fprintf(stderr, "Usage: %s file\n", argv[0]);
            return 1;
        }
        FILE *fp = fopen(argv[1], "r");
        if (fp == NULL)
        {
            perror("File does not open.");
            return 1;
        }
    
        int total_number_of_word = 1000;
        int total_number_of_same_word = 1000;
    
        struct word *essay = malloc(total_number_of_word * sizeof(struct word));
        struct same_word *unique_word = malloc(total_number_of_same_word * sizeof(struct same_word));
        assert(essay != 0);
        assert(unique_word != 0);
    
        int index = 0;
        int index2 = 0;
        int ret = 0;
        while (index < total_number_of_word)
        {
            if (fscanf(fp, "%s", essay[index].word) != 1)
                break;
            essay[index].occurrence = 1;
            ret = strcmp(essay[index].word, "Hello");
            if (ret == 0)
            {
                strcpy(unique_word[index2].word, essay[index].word);
                index2++;
            }
            index++;
        }
        fclose(fp);
        free(essay);
        free(unique_word);
        return 0;
    }
    

    示例运行(程序名称 wd ;源代码 wd.c ):

    $ make wd && valgrind wd wd.c
    gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror wd.c -o wd 
    ==24802== Memcheck, a memory error detector
    ==24802== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
    ==24802== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
    ==24802== Command: wd wd.c
    ==24802== 
    ==24802== 
    ==24802== HEAP SUMMARY:
    ==24802==     in use at exit: 22,233 bytes in 186 blocks
    ==24802==   total heap usage: 273 allocs, 87 frees, 538,561 bytes allocated
    ==24802== 
    ==24802== LEAK SUMMARY:
    ==24802==    definitely lost: 0 bytes in 0 blocks
    ==24802==    indirectly lost: 0 bytes in 0 blocks
    ==24802==      possibly lost: 0 bytes in 0 blocks
    ==24802==    still reachable: 0 bytes in 0 blocks
    ==24802==         suppressed: 22,233 bytes in 186 blocks
    ==24802== 
    ==24802== For counts of detected and suppressed errors, rerun with: -v
    ==24802== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 18 from 18)
    $
    

    在Mac OS X上,“退出时”和“已抑制”中使用的大量内存是正常的 .

    如果您遇到问题,那么一个可能的麻烦来源是您没有在两个阵列中分配足够的空间 . 你应该检查 indexindex2 的值是否在范围内 . 你可能有可能减少一个单词的长度 - 250相当长;我可能会用64代替 . 然后,您应该在 scanf() 格式字符串中使用 %63s 来防止溢出(或使用当前结构的 %249s ) . 源代码中只有136个单词,1241个字符 . 最长的'words'每个都是32个字符( malloc(total_number_of_same_word 是其中之一;另一个是 strcpy(unique_word[index2].word, ) .

  • 0

    感谢您的所有帮助,经过数千行代码的检查,我终于找到了程序中的问题所在 .

    因为我和另外4个人一起做小组工作 . 因此代码被4个不同的手触摸,我们的一个组伙伴创建了一个if语句,它将通过返回0结束程序 .

    但是她忘了释放我们一直在创建的所有堆内存,而不是发表任何代码 . 所以我没有 grab 这个愚蠢的问题 .

    我将发布我们之前拥有的错误代码和我们现在所拥有的CORRECT代码,以便为可能会遇到与我们相同的愚蠢问题的人发布 .

    这是我们代码的错误版本

    struct word{
          char word[250];
          int occurrence; };
    
        struct same_word{
          char word[250];};
    
        int main(int argc, char** agrv){
            FILE* fp;
            fp = fopen(argv[1],"r");//argv[1] is the location where we put the txt file name
            if(fp == NULL)
            {
                 perror("File does not open.");
                 exit(0);
            }
    
            int total_number_of_word = /*number of word I have in my txt file*/
            int total_number_of_same_word = /*number of same word I have in my txt file*/
            /* Assuming I knew these two numbers in advance*/
    
            struct word* essay = malloc(total_number_of_word * sizeof(struct word));
            struct same_word* unique_word = malloc(total_number_of_same_word * sizeof(struct same_word));
    
            int index = 0;
            int index2 = 0;
            int ret = 0;
            while(index < total_number_of_word){
                  fscanf(fp,"%s",essay[index].word);
                  essay[index].occurrence = 1;
                  ret = strcmp(essay[index].word,"Hello");
                  if( ret == 0)
                  {
                       strcpy(unique_word[index2].word,essay[index].word);
                       index2++;
                  }
                  index++;
            }
            //...
            if( /*a event is true*/)
            {
                  /*she has forgot to free memory before the return 0 
                    therefore we have been continuously leaking memory*/
                  return 0;
            }
            //...
            free(essay);
            free(unique_word);
            fclose(fp);
            return 0;
        }
    

    以下是out代码的正确版本

    struct word{
      char word[250];
      int occurrence;
    };
    
    struct same_word{
      char word[250];
    };
    
    int main(int argc, char** agrv){
        FILE* fp;
        fp = fopen(argv[1],"r");//argv[1] is the location where we put the txt file name
        if(fp == NULL)
        {
             perror("File does not open.");
             exit(0);
        }
    
        int total_number_of_word = /*number of word I have in my txt file*/
        int total_number_of_same_word = /*number of same word I have in my txt file*/
        /* Assuming I knew these two numbers in advance*/
    
        struct word* essay = malloc(total_number_of_word * sizeof(struct word));
        struct same_word* unique_word = malloc(total_number_of_same_word * sizeof(struct same_word));
    
        int index = 0;
        int index2 = 0;
        int ret = 0;
        while(index < total_number_of_word){
              fscanf(fp,"%s",essay[index].word);
              essay[index].occurrence = 1;
              ret = strcmp(essay[index].word,"Hello");
              if( ret == 0)
              {
                   strcpy(unique_word[index2].word,essay[index].word);
                   index2++;
              }
              index++;
        }
        //...
        if(/* a event is true*/)
        {
              free(essay);
              free(unique_word);
              fclose(fp);
              /* After freeing memory in here, we no longer have any memory leak*/
              return 0;
        }
        //...
        free(essay);
        free(unique_word);
        fclose(fp);
        return 0;
    }
    

    再次感谢大家的帮助 . 由于我不经常在这个平台上提问,我不知道问我问题的完美方式 . 我很抱歉没有在第一时间创建一个最小的,完整的,可验证的例子 .

    但是感谢你指出它,下次我提问时我会尽力做得更好 . 我非常感谢所有的解释和建议 .

相关问题