如果我在同一个指针 (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。您根本没有将指针指向mallocmalloc 总是分配新内存。因此,任何变量赋值都会发生同样的事情:

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:哎呀,太糟糕了。接得好。虽然如果 mallocrealloc 失败了,你可能会感到厌烦,但最好明确地处理它。【参考方案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 两次会发生啥?的主要内容,如果未能解决你的问题,请参考以下文章

malloc 用于 C 中的结构和指针

C语言里,啥时候用数组啥时候用指针和动态内存(malloc/calloc)?

malloc函数实现的功能是啥?

C程序定义一指针变量,直接令它赋值为NULL,不对它用malloc申请内存可以么?赋值和申请内存到底有啥区别

C指针原理(20)-C指针基础

何时将 malloc 用于 char 指针