如果我在同一个指针 (C) 上使用 malloc 两次会发生啥?
Posted
技术标签:
【中文标题】如果我在同一个指针 (C) 上使用 malloc 两次会发生啥?【英文标题】:What happens if I use malloc twice on the same pointer (C)?如果我在同一个指针 (C) 上使用 malloc 两次会发生什么? 【发布时间】:2013-10-26 10:58:36 【问题描述】:例如,我创建了一个指针 newPtr 并使用 malloc(some size),然后我再次使用 malloc(some size) 和相同的指针。发生什么了?然后我会创建与第一个相同大小的第二个内存块吗? newPtr 是否指向同一个地址?
例子:
int *newPtr;
newPtr = malloc(10 * sizeof(int));
newPtr = malloc(10 * sizeof(int));
【问题讨论】:
你要学习的重点是不要“在指针上使用malloc” 我问的原因是我试图理解链表。指针指向一个结构。那我不应该使用 malloc 吗? 指针和 malloc 都很好,问题是使用“malloc on a pointer”不是你在做什么。指针可以指向任何你想要它指向的地方,malloc
返回一个地址,指向它根据你的请求分配内存的位置。
【参考方案1】:
您的程序将发生内存泄漏。 newPtr
的第一个值将丢失,您将无法free
它。
然后我会创建与第一个大小相同的第二个内存块吗?
是的。您正在分配与第一个不同的第二个对象。
newPtr 是否指向同一个地址?
没有。对象是不同的,所以它们的地址是不同的。
【讨论】:
【参考方案2】:您实际上并没有在同一个指针上使用malloc
。您根本没有将指针指向malloc
。 malloc
总是分配新内存。因此,任何变量赋值都会发生同样的事情:
int a;
a = 14;
a = 20;
14
会发生什么?你不能再访问它了。就malloc
而言,这意味着您不再拥有对其返回的指针的引用,因此您将发生内存泄漏。
如果你真的想使用“malloc
和同一个指针”,你可能会对realloc
函数感兴趣:
int *newPtr;
newPtr = malloc(10 * sizeof(int));
newPtr = realloc(newPtr, 10 * sizeof(int)); //*might leak memory*
来自该链接:realloc
“更改 ptr 指向的内存块的大小。函数可能会将内存块移动到新位置(其地址由函数返回)。”
编辑:请注意,如果realloc
在上述情况下失败,则返回 NULL,但newPtr
指向的内存不会被释放。基于this answer,您可以这样做:
void *emalloc(size_t amt)
void *v = malloc(amt);
if(!v)
fprintf(stderr, "out of mem\n");
exit(EXIT_FAILURE);
return v;
void *erealloc(void *oldPtr, size_t amt)
void *v = realloc(oldPtr, amt);
if(!v)
fprintf(stderr, "out of mem\n");
exit(EXIT_FAILURE);
return v;
然后:
int *newPtr;
newPtr = emalloc(10 * sizeof(int));
newPtr = erealloc(newPtr, 10 * sizeof(int));
【讨论】:
在您的示例中,如果realloc
失败(返回NULL
)怎么办?内存泄漏!
@ouah:哎呀,太糟糕了。接得好。虽然如果 malloc
和 realloc
失败了,你可能会感到厌烦,但最好明确地处理它。【参考方案3】:
这些语句没有在 newPtr
上使用 malloc。
语句newPtr = malloc(10 * sizeof(int));
导致这些操作:
sizeof(int)
被评估。
该值乘以 10。
malloc
被调用,并且该产品被传递给它。
malloc
返回一个值。
该值分配给newPtr
。
所以你看,在第 3 步,newPtr
没有以任何方式参与。只有在malloc
完成后才会涉及newPtr
。
当您第二次拨打malloc
时,它无法知道您正在与newPtr
做任何事情。它只是分配新空间并返回一个指向它的指针。然后将该新指针分配给newPtr
,这将删除newPtr
中的旧值。
那时,您无法知道旧值是什么。空间仍然被分配,因为它没有被释放,但是你没有指向它的指针。
【讨论】:
【参考方案4】:您不是“在同一个指针上使用 malloc”。您正在调用malloc()
(它分配空间并返回指向该空间的指针)并将其返回值分配给同一指针对象。 (malloc
本身不知道你将如何处理它返回的结果。)
与任何赋值一样,第二个赋值将替换之前存储的值。
这意味着,除非您将其保存在其他地方,否则您将不再拥有指向第一个分配的内存块的指针。这是memory leak。
此外,您应该经常检查malloc
返回的结果是否为空指针,如果是,请采取一些纠正措施。在最简单的情况下,这可能只是打印一条错误消息并终止程序。您绝对应该不假设malloc
调用成功,然后尝试使用(不存在的)分配的内存。 (这与您的问题无关,但很容易错过,特别是因为在大多数情况下分配失败很少见。)
【讨论】:
以上是关于如果我在同一个指针 (C) 上使用 malloc 两次会发生啥?的主要内容,如果未能解决你的问题,请参考以下文章
C语言里,啥时候用数组啥时候用指针和动态内存(malloc/calloc)?