例如,我创建了一个指针 newPtr 并使用 malloc(some size),然后我再次使用 malloc(some size) 和相同的指针。怎么了?然后我会创建与第一个相同大小的第二个内存块吗?newPtr 是否指向同一个地址?
例子:
int *newPtr;
newPtr = malloc(10 * sizeof(int));
newPtr = malloc(10 * sizeof(int));
您的程序将发生内存泄漏。的第一个值newPtr
将丢失,您将无法获得free
它。
然后我会创建与第一个相同大小的第二个内存块吗?
是的。您正在分配第二个对象,与第一个对象不同。
newPtr 是否指向同一个地址?
不,对象是不同的,所以它们的地址是不同的。
您实际上并没有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
不会被释放。基于这个答案,你可以这样做:
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));
这些语句没有使用 malloc on newPtr
。
该语句newPtr = malloc(10 * sizeof(int));
导致这些操作:
sizeof(int)
被评估。malloc
被调用,并且该产品被传递给它。malloc
返回一个值。newPtr
。所以你看,在第 3 步,newPtr
没有以任何方式参与。只有在malloc
完成之后才newPtr
涉及。
当您malloc
第二次调用时,它无法知道您正在使用newPtr
. 它只是分配新空间并返回一个指向它的指针。然后将该新指针分配给newPtr
,这将删除 中的旧值newPtr
。
那时,您无法知道旧值是什么。空间仍然被分配,因为它没有被释放,但是你没有指向它的指针。
你不是“在同一个指针上使用 malloc”。您正在调用malloc()
(它分配空间并返回指向该空间的指针)并将其返回值分配给同一个指针对象。(malloc
它本身不知道你将如何处理它返回的结果。)
与任何赋值一样,第二个赋值将替换先前存储的值。
这意味着,除非您将其保存在其他地方,否则您将不再拥有指向第一个分配的内存块的指针。这是内存泄漏。
此外,您应该经常检查返回的结果是否malloc
为空指针,如果是,请采取一些纠正措施。在最简单的情况下,这可能只是打印一条错误消息并终止程序。您绝对不应该假设调用malloc
成功然后尝试使用(不存在的)分配的内存。(这与您的问题无关,但很容易错过,特别是因为在大多数情况下分配失败很少见。)