如果我在同一个指针(C)上使用malloc两次会怎么样?

时间:2013-10-17 19:23:30

标签: c pointers memory malloc

比如说我创建了一个指针newPtr,我使用了malloc(一些大小)然后我再次使用malloc(某个大小)和相同的指针。怎么了?我在创建第二块内存与第一块相同吗? newPtr是否指向同一地址?

示例:

int *newPtr;
newPtr = malloc(10 * sizeof(int));
newPtr = malloc(10 * sizeof(int));

4 个答案:

答案 0 :(得分:19)

您的程序会有内存泄漏。 newPtr的第一个值将丢失,您将无法free

  

我是否正在创建与第一个相同大小的第二块内存?

是。您正在分配第二个对象,与第一个对象不同。

  

newPtr是否指向同一地址?

没有。对象是不同的,因此它们的地址是不同的。

答案 1 :(得分:11)

你实际上并没有在同一个指针上使用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));

答案 2 :(得分:4)

这些陈述未在newPtr上使用malloc。

声明newPtr = malloc(10 * sizeof(int));导致这些操作:

    评估
  1. sizeof(int)
  2. 该值乘以10。
  3. 调用
  4. malloc,并将该产品传递给它。
  5. malloc返回一个值。
  6. 该值已分配给newPtr
  7. 所以你看,在第3步,newPtr没有任何参与。只有malloc完成后才会涉及newPtr

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

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

答案 3 :(得分:3)

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

第二项作业与任何作业一样,将取代先前存储的值。

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

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