解除分配无效双指针

Deallocating void double pointer

本文关键字:指针 无效 解除分配      更新时间:2023-10-16

如何释放空双指针?

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;

你的尝试非常好。你想要这样的东西:

void deallocate(void **ptr) {
    char *allocated = NULL;
    if (ptr) {
        allocated = *ptr;
    }
    if (allocated) {
        free(allocated);
        *ptr = NULL;
    }
}

你会这样称呼它:

deallocate(&allocated);

传入指针地址的原因是,可以在解除分配后将指针设置回 null。

你可能会使这比需要的更复杂。没有理由传递(例如 &allocated ( 到您的deallocate函数(除了将原始指针的值设置为 NULL而不使用返回符(。您可以简单地传递指针。是的,该函数将接收该指针的副本,但它仍将包含要释放的内存块的起始地址。例如:

void deallocate (void *ptr)
{
    if (!ptr) return;
    free (ptr);
}

如果你的目的是在deallocate函数中解除分配并设置原始指针指向NULL的值,那么是的,你确实需要传递原始地址,以便将指针设置为 NULL 反映在调用函数中(或者你可以使函数void *并返回指向设置为 null 的值的指针(。将参数作为void指针传递给deallocate,您可以执行以下操作:

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_deallocateallocate_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)

查看一下,如果您有任何问题,请告诉我。