如何释放void双指针?
deallocate(void** ptr)
这是我试图反对的情况:
char* allocated = (char*)allocate_array(sizeof(char), BUFSIZ,0);
deallocate_array((void**)&allocated);
我需要检查ptr是否为NULL,所以这是我的尝试:
if(ptr != NULL && *ptr != NULL){
free(*ptr);
}
ptr = NULL;
return;
答案 0 :(得分:2)
你的尝试非常好。你想要这样的东西:
void deallocate(void **ptr) {
char *allocated = NULL;
if (ptr) {
allocated = *ptr;
}
if (allocated) {
free(allocated);
*ptr = NULL;
}
}
你会这样称呼:
deallocate(&allocated);
传入指针地址的原因是,您可以在重新分配后将指针设置回null。
答案 1 :(得分:0)
你可能会使这比需要更复杂。没有理由将的地址(例如&allocated
)传递给deallocate
函数(除非将原始指针的值设置为NULL
而不使用回报)。你可以简单地传递一个指针。是的,该函数将接收该指针的副本,但它仍将包含要释放的内存块的起始地址。 e.g:
void deallocate (void *ptr)
{
if (!ptr) return;
free (ptr);
}
如果您的意图是解除分配并将原始指针指向的值设置为NULL
函数中的deallocate
,那么是的,您需要传递原始地址以便设置指向NULL
的指针会反映在调用函数中(或者您可以创建函数void *
并返回指向值设置为null的指针)。将参数作为deallocate
指针传递给void
,您可以执行以下操作:
void deallocate_doubleptr (void *ptr)
{
if (!ptr || !*(void **)ptr) return;
free (*(void **)ptr);
*(void **)ptr = NULL;
}
(注意:,你没有传递void **
参数,你只需传递一个void *
(void)指针并根据需要在函数中进行转换。参数是仍然是void
指针。)
一个简短的例子说明两者都是等价的,除了NULL
的明确赋值,并猜测你的allocate_array
会是什么:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void *allocate_array (size_t size, size_t nmemb, int set);
void deallocate (void *ptr);
void deallocate_doubleptr (void *ptr);
int main (int argc, char **argv) {
size_t size = argc > 1 ? (size_t)strtoul (argv[1], NULL, 10) : 1;
size_t nmemb = argc > 2 ? (size_t)strtoul (argv[2], NULL, 10) : 128;
int set = argc > 3 ? (int)strtol (argv[3], NULL, 10) : 0;
char *str = "The quick brown fox jumps over a lazy dog.";
char *allocated = NULL;
if ((allocated = allocate_array (size, nmemb, set)))
printf ("\nsuccessfully allocated '%zu' bytes initialized to '%d' ('%c').\n",
size * nmemb, set, set);
if (31 < set && set < 127) { /* if filled with printable ASCII */
allocated[strlen (str)] = 0; /* nul-terminate */
printf ("allocated : '%s'\n", allocated); /* output array */
}
strncpy (allocated, str, size * nmemb - 1); /* copy str to array */
allocated[size * nmemb - 1] = 0; /* nul-terminate */
printf ("allocated : '%s'\n", allocated); /* output */
#ifdef DEALLOCDBL
deallocate_doubleptr (&allocated);
printf ("deallocated all memeory, pointer reinitialized to 'NULL'\n");
#else
deallocate (allocated);
printf ("deallocated all memeory.\n");
#endif
return 0;
}
void *allocate_array (size_t size, size_t nmemb, int set)
{
if (!size || !nmemb) {
fprintf (stderr, "error: invalid size or number of members.\n");
return NULL;
}
void *memptr = NULL;
if (set != 0) {
memptr = malloc (nmemb * size);
memset (memptr, set, nmemb * size);
}
else
memptr = calloc (nmemb, size);
if (!memptr) {
fprintf (stderr, "error: virtual memory exhausted.\n");
exit (EXIT_FAILURE);
}
return memptr;
}
void deallocate (void *ptr)
{
if (!ptr) return;
free (ptr);
ptr = NULL;
}
void deallocate_doubleptr (void *ptr)
{
if (!ptr || !*(void **)ptr) return;
free (*(void **)ptr);
*(void **)ptr = NULL;
}
<强>编译强>
gcc -Wall -Wextra -o bin/allocate_deallocate allocate_deallocate.c
或
gcc -Wall -Wextra -DDEALLOCDBL -o bin/allocate_deallocate_dbl allocate_deallocate.c
(大多数编译器应采用相同或非常相似的选项)
<强>输出强>
无论调用的实现如何,输出都是相同的。 (例如allocate_deallocate
或allocate_deallocate_dbl
):
$ ./bin/allocate_deallocate 1 64 65
successfully allocated '64' bytes initialized to '65' ('A').
allocated : 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
allocated : 'The quick brown fox jumps over a lazy dog.'
deallocated all memeory.
内存/错误检查
$ valgrind ./bin/allocate_deallocate 1 64 65
或
$ valgrind ./bin/allocate_deallocate_dbl 1 64 65
==13759== Memcheck, a memory error detector
==13759== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==13759== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==13759== Command: ./bin/allocate_deallocate
==13759==
successfully allocated '64' bytes initialized to '65' ('A').
allocated : 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
allocated : 'The quick brown fox jumps over a lazy dog.'
deallocated all memeory, pointer reinitialized to 'NULL'
==13759==
==13759== HEAP SUMMARY:
==13759== in use at exit: 0 bytes in 0 blocks
==13759== total heap usage: 1 allocs, 1 frees, 64 bytes allocated
==13759==
==13759== All heap blocks were freed -- no leaks are possible
==13759==
==13759== For counts of detected and suppressed errors, rerun with: -v
==13759== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
仔细看看,如果您有任何问题,请告诉我。