【问题标题】:Can't free malloc in c [duplicate]无法在c中释放malloc [重复]
【发布时间】:2020-05-12 02:16:27
【问题描述】:

我是 C 的新手。我有以下代码。在free之后,第一个释放的指针长度为0但不为空,第二个和第三个的长度仍然> 0。不知道是否正常?谢谢。 这是输出: enter image description here

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    char *str[3];
    char *aa = "helloworld0";
    char *bb = "helloworld1";
    char *cc = "helloworld2";
    str[0] = (char *)malloc(strlen(aa) + 1);
    strcpy(str[0], aa);
    str[1] = (char *)malloc(strlen(bb) + 1);
    strcpy(str[1], bb);
    str[2] = (char *)malloc(strlen(cc) + 1);
    strcpy(str[2], cc);

    char **strr = str;

    printf("Before free----Length:%ld,Content:%s,Address:%p\n",
           strlen(strr[1]), strr[1], strr[1]);
    free(strr[1]);
    if (strr[1]) printf("not NULL 1\n");
    printf("After free----Length:%ld,Content:%s,Address:%p\n\n",
           strlen(strr[1]), strr[1], strr[1]);

    printf("Before free----Length:%ld,Content:%s,Address:%p\n",
           strlen(strr[0]), strr[0], strr[0]);
    free(strr[0]);
    if (strr[0] == NULL) printf("not NULL 0\n");
    printf("After free----Length:%ld,Content:%s,Address:%p\n\n",
           strlen(strr[0]), strr[0], strr[0]);

    printf("Before free----Length:%ld,Content:%s,Address:%p\n",
           strlen(strr[2]), strr[2], strr[2]);
    free(strr[2]);
    if (strr[2]) printf("not NULL 2\n");
    printf("After free----Length:%ld,Content:%s,Address:%p\n\n",
           strlen(strr[2]), strr[2], strr[2]);
}

【问题讨论】:

  • 欢迎来到 SO!调用free后,就不能再访问数据了,所以这个程序的行为是不确定的。

标签: c malloc free


【解决方案1】:

将指针值传递给free 后,对该值的任何进一步使用都会产生未定义的行为。即使if (strr[1]) 是无效的并且没有有意义的结果,即使在实践中它通常反映上次值是有意义的,它是非空的。

后面的操作就更惨了:

printf("After free----Length:%ld,Content:%s,Address:%p\n\n",strlen(strr[1]),strr[1],strr[1]);

在这里,您不仅使用了值strr[1](一个指针),而且还传递了一个函数,该函数将使用它来访问该地址(strlen)处的对象。这也有未定义的行为,并且最终会访问不再属于您的程序的内存。这会导致编译器实现如何处理它可以看到的未定义行为(注意:它甚至可以在让你达到这一点之前陷入困境,但它不是必须的)以及可能在 C 库实现(@ 987654326@) 与你放弃的记忆有关。该地址可能不再起作用,并且访问它会出错并导致您的程序崩溃。它也有可能最终访问现在属于实现的内存,可能会在那里存储新内容以跟踪它以供重用。也有可能产生完全不同和意想不到的结果。

在 C 语言中,您根本无法做到这一点。在你free 获得malloc 的内存之后,你就完成了。您无法以任何方式处理指针或它之前指向的内存。没有办法“检查它是否被释放”。一旦它被释放,就是这样。

许多程序员喜欢在释放指针对象指向的内存后立即为其分配一个空指针值,以防止以后无意中尝试访问它:

strr[1] = NULL;    // or = 0;

【讨论】:

    【解决方案2】:

    释放内存实际上意味着释放内存中指定位置的所有权。这个想法是,在释放它的过程中,它自己不能再从给定位置写出变量,而只能读取。为了在每次释放后真正使代码安全,您应该将变量设置为 NULL。它会将变量从它指向的最后一个内存的销售中重定向,并使数据无法从它自己的变量中读取。相反,指针将持有一个 NULL,这是一个无所有权的指针的预知状态,因此可以使用。

    【讨论】:

    • 不能再从给定位置写入,只能读取?一旦块被释放,使用指针读取和写入都具有未定义的行为。
    【解决方案3】:

    free 表示你在告诉系统:

    我不再需要这个内存了,你可以随时使用这个内存。

    但系统不保证什么时候清理和重用这些内存。

    下次访问此内存时,可能系统还没有清理它,或者它可能已经清理了。你只是不能确定它是否确实如此。这是一种未定义的行为。

    您应该添加strr[1]=NULL;以防止您意外访问您已经返回系统的空间。

    【讨论】:

      猜你喜欢
      • 2015-07-22
      • 2012-02-07
      • 2013-05-06
      • 1970-01-01
      • 2016-02-28
      • 2015-09-10
      • 1970-01-01
      • 2016-04-06
      相关资源
      最近更新 更多