22

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

例子:

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

4 回答 4

26

您的程序将发生内存泄漏。的第一个值newPtr将丢失,您将无法获得free它。

然后我会创建与第一个相同大小的第二个内存块吗?

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

newPtr 是否指向同一个地址?

不,对象是不同的,所以它们的地址是不同的。

于 2013-10-17T19:24:17.237 回答
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不会被释放。基于这个答案,你可以这样做:

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));
于 2013-10-17T19:25:29.377 回答
4

这些语句没有使用 malloc on newPtr

该语句newPtr = malloc(10 * sizeof(int));导致这些操作:

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

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

当您malloc第二次调用时,它无法知道您正在使用newPtr. 它只是分配新空间并返回一个指向它的指针。然后将该新指针分配给newPtr,这将删除 中的旧值newPtr

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

于 2013-10-17T19:27:52.580 回答
3

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

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

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

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

于 2013-10-17T19:25:36.253 回答