[英]Two pointers are pointing to same memory address, how to avoid memory leak in case freeing of these two happens at independence place?
int *a = malloc(40);
int *b;
b=a;
if( *some conditions* )
free(a);
// I know that 'a' has been allocated this chunk of memory X times
// and free(a) has been called less than X times.
I have no idea of that condition, so don't know whether 'a' has been freed or not! 我不知道这种情况,所以不知道“ a”是否已释放! So now how would I be sure if 'b' ie 'a' has been freed or not.
因此,现在我将如何确定是否释放了“ b”即“ a”。
If you want to make sure that subsequent calls of free
on a pointer to dynamically allocated memory will not do any harm, you should assign NULL
to that pointer. 如果要确保对动态分配的内存的指针的后续
free
调用不会造成任何损害,则应为该指针分配NULL
。 Because (emphasis added): 因为(添加了重点):
The free() function frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc().
free()函数释放ptr指向的内存空间,该内存空间必须已由先前对malloc(),calloc()或realloc()的调用返回。 Otherwise, or if free(ptr) has already been called before, undefined behavior occurs.
否则,或者如果之前已经调用过free(ptr),则会发生未定义的行为。 If ptr is NULL, no operation is performed.
如果ptr为NULL,则不执行任何操作。
If you want to make sure that pointer b
will always refer to the same object the other pointer a
points at, you could turn b
into a pointer to a
instead (and dereference it each time you need to use it): 如果你想确保指针
b
将永远指向同一个对象的其他指针a
点,你可以把b
成一个指向a
来代替(解引用它每次你需要使用它的时间):
#include <stdio.h>
#include <stdlib.h>
int main() {
/* dynamically allocate some memory */
int *a = malloc(40);
/* b is a pointer to a pointer to an int */
int **b;
/* make b point to a */
b = &a;
if ( 1 ) {
/* free memory and assign NULL to the pointer */
free(a);
a = NULL;
}
/* nothing bad will happen when we dereference b now */
printf("%p\n", *b);
/* nothing bad will happen when we free the memory region
where the pointer b points to points to */
free(*b);
}
Another thing on memory leaks. 内存泄漏的另一件事。 There will be no memory leaked when you double-free the memory.
双重释放内存时,不会有内存泄漏。 In that case you will stumble into undefined behavior, in which case anything could happen .
在这种情况下,您会陷入不确定的行为,在这种情况下可能会发生任何事情 。 Simply because you shall not access memory regions that are not your own (anymore) (cf, this great post) .
仅仅因为您将不访问不是您自己的内存区域(不再) (参见此好帖子) 。 Instead, you will leak memory when you loose the reference to a block of dynamically allocated memory.
相反,当您丢失对动态分配的内存块的引用时,您将泄漏内存。 For example:
例如:
/* allocate some memory */
int *a = malloc(40);
/* reassign a without free-ing the memory before : you now have leaked memory */
a = malloc(40);
The best option is not having two pointers, pointing to the same place, which are freed independently. 最好的选择是没有两个指向同一位置的指针被独立释放。
But if that's really what you need, then you need a reference count. 但是,如果这确实是您所需要的,那么您需要一个参考计数。
The following code implements a very simple reference count mechanism. 以下代码实现了一个非常简单的引用计数机制。
When you assign a second pointer to your data, you should use clone_x
to increment the reference count. 当为数据分配第二个指针时,应使用
clone_x
增加引用计数。
Each time you free, use free_x
, and it will free just once. 每次释放时,请使用
free_x
,它将释放一次。
Note that this code isn't multithread-safe. 请注意,此代码不是多线程安全的。 If your code is multi-threaded, you need atomic operations, and you need to be very careful with how you use them.
如果您的代码是多线程的,则需要原子操作,并且在使用它们时需要非常小心。
struct x {
int refcount;
int payload;
};
struct x *create_x(int payload) {
struct x *newx = malloc(sizeof(*newx));
if (!newx) return NULL;
newx->payload = payload;
newx->refcount = 1;
return newx;
}
void clone_x(struct x *myx) {
myx->refcount++;
}
void free_x(struct x *oldx) {
oldx->refcount--;
if (oldx->refcount == 0) {
free(oldx);
}
}
You can't. 你不能 When
free(a)
is called it is no longer safe to access that memory. 调用
free(a)
,访问该内存不再安全。
Even if you malloc()
new memory and assign the result to a
, that memory could be anywhere. 即使你
malloc()
新的内存和分配结果a
,内存可以在任何地方。
What you're trying to do will not work. 您尝试执行的操作无效。
每个分配的内存块都应有一个“所有者”,a或b,如果a是所有者,则指针b不应释放该块,反之亦然。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.