【问题标题】: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 返回一个地址,指向它根据你的请求分配内存的位置。

标签: c pointers memory 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)); 导致这些操作:

    1. sizeof(int) 被评估。
    2. 该值乘以 10。
    3. malloc 被调用,并且该产品被传递给它。
    4. malloc 返回一个值。
    5. 该值分配给newPtr

    所以你看,在第 3 步,newPtr 没有以任何方式参与。只有在malloc 完成后才会涉及newPtr

    当您第二次拨打malloc 时,它无法知道您正在与newPtr 做任何事情。它只是分配新空间并返回一个指向它的指针。然后将该新指针分配给newPtr,这将删除newPtr 中的旧值。

    那时,您无法知道旧值是什么。空间仍然被分配,因为它没有被释放,但是你没有指向它的指针。

    【讨论】:

      【解决方案4】:

      您不是“在同一个指针上使用 malloc”。您正在调用malloc()(它分配空间并返回指向该空间的指针)并将其返回值分配给同一指针对象。 (malloc 本身不知道你将如何处理它返回的结果。)

      与任何赋值一样,第二个赋值将替换之前存储的值。

      这意味着,除非您将其保存在其他地方,否则您将不再拥有指向第一个分配的内存块的指针。这是memory leak

      此外,您应该经常检查malloc返回的结果是否为空指针,如果是,请采取一些纠正措施。在最简单的情况下,这可能只是打印一条错误消息并终止程序。您绝对应该假设malloc 调用成功,然后尝试使用(不存在的)分配的内存。 (这与您的问题无关,但很容易错过,特别是因为在大多数情况下分配失败很少见。)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-02
        • 2019-01-13
        • 2011-04-19
        • 2016-08-21
        • 2011-02-14
        • 1970-01-01
        • 2022-12-04
        • 1970-01-01
        相关资源
        最近更新 更多