您可能会让这变得比需要的更复杂。没有理由将的地址(例如&allocated)传递给您的deallocate 函数(除了将原始指针的值设置为NULL 而不使用返回)。您可以简单地传递一个指针。是的,该函数将接收该指针的副本,但它仍将包含要释放的内存块的起始地址。例如:
void deallocate (void *ptr)
{
if (!ptr) return;
free (ptr);
}
如果您的意图是在您的 deallocate 函数中解除分配并将原始指针指向的值设置为 NULL,那么是的,您确实需要传递原始地址以便将指针设置为 @ 987654327@ 反映在调用函数中(或者您可以将函数设为 void * 并返回指向设置为 null 的值的指针)。将传递给deallocate 的参数保留为void 指针,您可以执行以下操作:
void deallocate_doubleptr (void *ptr)
{
if (!ptr || !*(void **)ptr) return;
free (*(void **)ptr);
*(void **)ptr = NULL;
}
(注意:,您没有传递void ** 参数,您只需传递一个void * (void) 指针并在函数内根据需要进行强制转换。参数仍然是@987654334 @指针。)
一个简短的例子说明两者是等价的,除了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)
查看一下,如果您有任何问题,请告诉我。