Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 两个指针指向同一个内存地址,如果这两个指针在独立位置释放,如何避免内存泄漏?_C_Pointers - Fatal编程技术网

C 两个指针指向同一个内存地址,如果这两个指针在独立位置释放,如何避免内存泄漏?

C 两个指针指向同一个内存地址,如果这两个指针在独立位置释放,如何避免内存泄漏?,c,pointers,C,Pointers,我不知道这种情况,所以不知道“a”是否已被释放!那么现在我如何确定“b”即“a”是否被释放。你不能。调用free(a)时,访问该内存不再安全 即使您malloc()新建内存并将结果分配给a,该内存也可能位于任何位置 你想做的事行不通。你做不到。调用free(a)时,访问该内存不再安全 即使您malloc()新建内存并将结果分配给a,该内存也可能位于任何位置 您尝试执行的操作将不起作用。如果要确保对指向动态分配内存的指针的free的后续调用不会造成任何损害,则应将NULL分配给该指针 free()

我不知道这种情况,所以不知道“a”是否已被释放!那么现在我如何确定“b”即“a”是否被释放。

你不能。调用
free(a)
时,访问该内存不再安全

即使您
malloc()
新建内存并将结果分配给
a
,该内存也可能位于任何位置

你想做的事行不通。

你做不到。调用
free(a)
时,访问该内存不再安全

即使您
malloc()
新建内存并将结果分配给
a
,该内存也可能位于任何位置


您尝试执行的操作将不起作用。

如果要确保对指向动态分配内存的指针的
free
的后续调用不会造成任何损害,则应将
NULL
分配给该指针

free()函数释放ptr指向的内存空间,该内存空间必须由以前对malloc()、calloc()或realloc()的调用返回。否则,或者如果之前已经调用了free(ptr),则会发生未定义的行为如果ptr为空,则不执行任何操作。


如果要确保指针
b
始终指向另一个指针
a
指向的同一对象,可以将
b
改为指向
a
的指针(并在每次需要使用时取消引用):


如果要确保对指向动态分配内存的指针的
free
的后续调用不会造成任何损害,则应将
NULL
分配给该指针

free()函数释放ptr指向的内存空间,该内存空间必须由以前对malloc()、calloc()或realloc()的调用返回。否则,或者如果之前已经调用了free(ptr),则会发生未定义的行为如果ptr为空,则不执行任何操作。


如果要确保指针
b
始终指向另一个指针
a
指向的同一对象,可以将
b
改为指向
a
的指针(并在每次需要使用时取消引用):


每个分配的内存块都应该有一个“所有者”,a或b,如果a是所有者,指针b不应该释放该块,反之亦然

每个分配的内存块都应该有一个“所有者”,a或b,如果a是所有者,指针b不应该释放该块,反之亦然

最好的选择是不要有两个指向同一位置的指针,它们是独立释放的。
但如果这真的是你需要的,那么你需要一个参考计数

下面的代码实现了一个非常简单的引用计数机制。
当为数据分配第二个指针时,应使用
clone\u x
增加引用计数。
每次您释放时,使用
free\u x
,它只会释放一次

请注意,此代码不是多线程安全的。如果您的代码是多线程的,那么您需要原子操作,并且您需要非常小心地使用它们

/* allocate some memory */
int *a = malloc(40);
/* reassign a without free-ing the memory before : you now have leaked memory */
a = malloc(40);

最好的选择是不要有两个指向同一位置的指针,它们是独立释放的。
但如果这真的是你需要的,那么你需要一个参考计数

下面的代码实现了一个非常简单的引用计数机制。
当为数据分配第二个指针时,应使用
clone\u x
增加引用计数。
每次您释放时,使用
free\u x
,它只会释放一次

请注意,此代码不是多线程安全的。如果您的代码是多线程的,那么您需要原子操作,并且您需要非常小心地使用它们

/* allocate some memory */
int *a = malloc(40);
/* reassign a without free-ing the memory before : you now have leaked memory */
a = malloc(40);

“我不知道这种情况,所以不知道‘a’是否被释放了!”在这种情况下,你就被用水管冲洗了。你当然可以猜到,有一半的时间你猜对了。您必须记录哪些内存需要释放,哪些不能释放。如果您不知道,泄漏是您所能期望的最好结果。“我知道[…]free(a)的调用次数不到X次。”请确切地告诉我们您所知道的内容。我认为标题太短了。每当您处理动态分配的对象时,必须有一个关于这些对象所有权的策略。只有所有者可以释放对象,并且所有权可以转移(当发生这种情况时是策略/设计决策)。对于如何处理C中的所有权策略,没有任何单一的答案。引用计数是一种选择;另一个问题是,在传递/返回指向/来自某个对象的指针时只需编写文档即可转移所有权。但是作为一个程序员,你需要知道哪个指针拥有这个对象,以及这个所有权何时被转移。@MichaelBurr我认为你应该把它作为一个答案。“我不知道那个条件,所以不知道‘a’是否被释放了!”在这种情况下,你就被套住了。你当然可以猜到,有一半的时间你猜对了。您必须记录哪些内存需要释放,哪些不能释放。如果您不知道,泄漏是您所能期望的最好结果。“我知道[…]free(a)的调用次数不到X次。”请确切地告诉我们您所知道的内容。我认为标题太短了。每当您处理动态分配的对象时,必须有一个关于这些对象所有权的策略。只有所有者可以释放对象,并且所有权可以转移(当发生这种情况时是策略/设计决策)。对于如何处理C中的所有权策略,没有任何单一的答案。引用计数是一种选择;另一个问题是,在传递/返回指向/来自某个对象的指针时只需编写文档即可转移所有权。但是作为一个程序员,你需要知道哪个指针拥有这个对象,以及这个所有权何时转移。@MichaelBurr我想你应该把它作为一个答案。
/* allocate some memory */
int *a = malloc(40);
/* reassign a without free-ing the memory before : you now have leaked memory */
a = malloc(40);
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);
    }
}