【发布时间】:2011-01-26 17:06:25
【问题描述】:
谁能告诉我:
int *p;
p=(int*)malloc(10*sizeof(int));
free(p);
或
int *p;
p=(int*)malloc(10*sizeof(int));
p=NULL;
【问题讨论】:
-
C 不是 Java。 :)
谁能告诉我:
int *p;
p=(int*)malloc(10*sizeof(int));
free(p);
或
int *p;
p=(int*)malloc(10*sizeof(int));
p=NULL;
【问题讨论】:
free 将释放 p 指向的内存 - 只需将其分配给 NULL 不会(因此您将有内存泄漏)。
值得一提的是,在调用free 之后将指针分配给NULL 是一种很好的做法,因为这将防止您意外尝试访问已释放的内存(这仍然是可能的,但绝对应该未完成)。
【讨论】:
C 中没有垃圾回收,因此如果您不显式释放一块内存,即使没有对它的引用,它也永远不会被释放。也许您来自垃圾收集语言的背景,因此可能很难改变您的思维方式,但记住“手动”释放所有低级语言(如 C)的资源始终很重要。
希望这会有所帮助 干杯
【讨论】:
p 是指针(指向内存中动态分配的块 [“在堆上”])
这意味着 p 是一个变量,其中包含特定块的内存中的 地址(或某些特定大小,在示例中,块大到足以容纳 10 个整数)。
free(p); 指示(C 运行时的)内存管理逻辑,p 指向的块先前占用的内存可以被重用。
p = NULL; 将 p 的值设置为 NULL(它之前包含的地址已丢失)但它指向的内存中的块仍然被认为是在使用中。
可能会有一些混淆,因为在 Java、C#、Python 等语言中,仅将变量分配给 NULL(或其他地址),将自动释放底层内存(假设没有其他对该地址的引用存在于其他实时变量中)。
在 C 或 C++ 中不是这种情况,会导致如下错误:
free(p);
// possibly some some code etc.
// later:
p[6] = 'a'; // <<--- Ouch we're modifying whatever new variable is there !!!
或
// didn't call free(p)
p = NULL;
// now the memory allocated for p is held in memory even though it
// is not going to be used (assuming no copies of p or of pointers to part
// of that block were made.
后一种情况只会浪费资源,前一种情况会导致难以发现的bug。
这就是为什么一个典型的 C 习语是:
free(p);
p = NULL;
【讨论】:
不调用 free 直接赋值为 NULL 会导致内存泄漏,正如其他人解释的那样。您可以参考此link 以获得有关内存泄漏和其他内存相关问题的详细信息。
【讨论】:
更好的办法是先释放内存,然后设置为NULL:
free(p);
p = NULL;
【讨论】:
释放分配的内存会释放它,并允许在其他地方使用该内存,同时保留指向内存分配位置的指针。
将指向已分配内存的指针设置为 NULL 不会释放它。
如果您使用的是使用基于堆的 malloc 的实现,请调试分配、使用和释放内存的内容,并对分配、使用和将指向内存的指针设置为 NULL 的内容执行相同的操作。
内存管理依赖于实现(参见http://en.wikipedia.org/wiki/Malloc#Implementations)。
【讨论】:
1.
int *p;
p= (int * ) malloc(10*sizeof(int));
free(p);
内存被释放回堆。但指针仍指向已释放的内存位置。因此,如果进一步使用,将导致内存损坏。
因此正确的做法是将指针显式重置为 NULL 以避免进一步使用该指针。
不建议在 C 中类型转换返回指针
2.
int *p;
p=(int * )malloc(10*sizeof(int));
p=NULL;
这会导致内存泄漏:因为分配的内存没有在这里释放。您只是将指针重置为 NULL。
【讨论】:
p=NULL 不会释放内存。如果您不再需要使用p 指向的内存,则应使用free(),否则会出现内存泄漏。您还应该在调用free() 之后设置p=NULL,以避免将来再次错误地访问该内存。
【讨论】: