【问题标题】:Memory Allocation C内存分配 C
【发布时间】:2012-09-27 20:57:43
【问题描述】:

我有一个内存分配问题。如果我在else 块中声明char*,这意味着char*else 块执行完毕时被销毁。 else 块位于 while 循环中,因此它会迭代很多次。但是,如果在 else 块中声明的 char* 别名为 malloc'd 变量,如下例所示。我的问题是我如何收取这样的费用?我觉得如果我释放 temp char* 变量,我会导致分段错误,因为我也会释放我想要保留的变量。如果是这样的话,我不知道free 语句的去向。

char* print_path = NULL;

(截图)

  (while)

 else{
        char* temp_path = print_path;
        int temp_size = strlen(temp_path)+strlen(file_name(child->fts_path))+1;
        print_path = (char*)malloc(temp_size);
        strcpy(print_path, temp_path);
        strncat(print_path, file_name(child->fts_path), strlen(file_name(child->fts_path)));
        printf("%s:\n\n", print_path);
        }

(截图)

我想指出,在我知道它不会再次执行之后,我在程序末尾执行了 free print_path。但是,我想释放的是循环的中间执行。任何帮助,将不胜感激。 谢谢!

【问题讨论】:

  • 您混淆了堆栈分配和堆分配的内容。您不是在释放指针,而是在释放指针指向的内存。
  • 在循环的每次迭代中释放的意义何在?你知道在循环期间你将需要那段内存,释放和重新分配在这里没有多大意义。
  • @JordanKaye 在每次迭代期间释放的要点是因为不再需要前一次迭代的动态分配变量。如果在足够长的数据样本上运行,则将没有内存。在不再需要时释放所有 malloc 变量也是一种很好的编程习惯。

标签: c memory pointers free


【解决方案1】:

看起来free(temp_path) 是正确的。它应该是这样的:

char * print_path = malloc(...);    // "NULL" is also possible

while (condition)
{
    if (...)
    {
         // ...
    }
    else
    {
        char * temp_path = print_path;

        print_path = malloc(...);

        free(temp_path);
    }
}

free(print_path);

您的算法中的不变量是(或应该是)print_path 始终指向动态分配的内存。请注意,每个malloc 都有一个free

【讨论】:

  • 是的,那是我最初拥有 free(temp_path) 语句的地方,但是我遇到了分段错误,但我认为我可能做错了什么,因为我几乎肯定 @987654327 @应该去那里。会不会 temp_path 实际上不是动态分配的内存块?
【解决方案2】:

我相信,既然我想做的是将内存重新分配给同一个变量,我应该研究 realloc 而不是 malloc。

【讨论】:

    【解决方案3】:

    你有 2 个指针:

    print_paths:指向一个类似['h','e','l','l','o']的数组,这个指针包含数组第一个元素的地址,在这种情况下它指向h,假设这个h的地址是1,所以,e 的地址是2 等等......因此,print_path 包含数字1

    temp_path: 这个指针指向什么都没有或指向内存中的一个随机位置。

    当你调用malloc时,malloc请求一些内存并给你新分配内存的地址,但是这个内存包含垃圾。

    所以之后

    print_path = (char*)malloc(temp_size);
    

    print_path 包含新分配内存的地址,一个大小为temp_size 的新数组有垃圾,假设这个地址是40,所以print_path 的值是40

    最后,当你打电话时:

    strcpy(print_path, temp_path);
    

    您将数组temp_path (['h','e','l','l','o']) 的值复制到print_path 指向的数组中,换句话说,地址40 不再包含垃圾,现在包含h41 包含e 等等。

    请务必注意,即使两个地址(140)都包含值 h,修改一个不会影响另一个。

    free(temp_path) 的最佳位置是在 else 结束之前,只要检查 temp_path 是否已分配内存,如果您尝试释放不是通过 malloc 获得的内存你的'我会过得很糟糕的。

    【讨论】:

    • 谢谢,但是我在发帖之前已经尝试过了,因为我把它放在那里时出现了分段错误。难道是因为temp_pathprint_path的副本,而不是动态分配的?
    • @tpar44 可能是因为您的第一个 print_pathNULL,您是否要释放 NULL 指针?如果您的第一个 print_path 不是,请尝试类似 if (temp_path!=NULL) free(temp_path);一个NULL 指针,可能你正在分配给temp_path 类似temp_path=child->fts_path 的东西,即你正在分配给temp_path 稍后要使用的内存,所以,你在这部分代码中释放它,然后你稍后尝试访问它
    猜你喜欢
    • 2015-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多