C 解除分配多个内存指针最方便的方法是什么?

C 解除分配多个内存指针最方便的方法是什么?,c,memory-management,memory-leaks,heap-memory,dynamic-memory-allocation,C,Memory Management,Memory Leaks,Heap Memory,Dynamic Memory Allocation,我正在寻找多内存释放的最方便/最好/最智能的方法。不太确定这是否是最好的解释,但下面是一个例子,可以说明我想做什么: void func() { int* ptr1 = malloc(1); if(ptr1 == NULL) { //... } int* ptr2 = malloc(1); if(ptr2 == NULL) { //... free(ptr1); } int

我正在寻找多内存释放的最方便/最好/最智能的方法。不太确定这是否是最好的解释,但下面是一个例子,可以说明我想做什么:

void func()
{
    int* ptr1 = malloc(1);
    if(ptr1 == NULL)
    {
        //...
    }

    int* ptr2 = malloc(1);
    if(ptr2 == NULL)
    {
        //...
        free(ptr1);
    }

    int* ptr3 = malloc(1);
    if(ptr3 == NULL)
    {
        //...
        free(ptr2);
        free(ptr1);
    }

    //code...
}

我想到的唯一一件事是数组中充满了标志,如果标志被升起,则必须释放特定的内存。还有其他更方便的方法吗?您可以想象,如果需要更多的
malloc()
-ing,我需要重复多少次
free()

您可以使用一个
指针数组
,并对
malloc
的数量进行计数。并使用一个公共的free函数来
释放它们。像

void func()
{
    char* ptr[10];
    int n = 0, i;

    for(i = 0; i < 10; i++)
        ptr[i] = NULL;

    ptr[n] = malloc(1);
    if(ptr[n] == NULL)
    {
        //...
    }
    n++;

    ptr[n] = malloc(1);
    if(ptr[n] == NULL)
    {
        //...
        custom_free(ptr1, n);
    }
    n++;

    ptr[n] = malloc(1);
    if(ptr[n] == NULL)
    {
        //...
        custom_free(ptr, n);
    }
    n++;
    //code...
}

您可以使用指针的
数组
,并对
malloc
的数量进行计数。并使用一个公共的free函数来
释放它们。像

void func()
{
    char* ptr[10];
    int n = 0, i;

    for(i = 0; i < 10; i++)
        ptr[i] = NULL;

    ptr[n] = malloc(1);
    if(ptr[n] == NULL)
    {
        //...
    }
    n++;

    ptr[n] = malloc(1);
    if(ptr[n] == NULL)
    {
        //...
        custom_free(ptr1, n);
    }
    n++;

    ptr[n] = malloc(1);
    if(ptr[n] == NULL)
    {
        //...
        custom_free(ptr, n);
    }
    n++;
    //code...
}

您发布的内容是函数中错误处理和资源释放的常见做法,您获取了多个资源,如果发生任何错误,您需要释放之前获取的资源,没有问题,只需逐个执行即可

void func(void) {
    void *ptr1 = NULL;
    void *ptr2 = NULL;
    void *ptr3 = NULL;

    ptr1 = malloc(SIZE);
    if (!ptr1) goto end;

    ptr2 = malloc(SIZE);
    if (!ptr2) goto end;

    ptr3 = malloc(SIZE);
    if (!ptr3) goto end;

    // do your work with the buffers

end:
    free(ptr1);
    free(ptr2);
    free(ptr3);
}

您发布的内容是函数中错误处理和资源释放的常见做法,您获取了多个资源,如果发生任何错误,您需要释放之前获取的资源,没有问题,只需逐个执行即可

void func(void) {
    void *ptr1 = NULL;
    void *ptr2 = NULL;
    void *ptr3 = NULL;

    ptr1 = malloc(SIZE);
    if (!ptr1) goto end;

    ptr2 = malloc(SIZE);
    if (!ptr2) goto end;

    ptr3 = malloc(SIZE);
    if (!ptr3) goto end;

    // do your work with the buffers

end:
    free(ptr1);
    free(ptr2);
    free(ptr3);
}

另一种方法是将所有需要的内存分配到一个大内存块中, 并将其部分视为p0,p1,p2:

void worker(void)
{
#define N_ELEM 123
int *work_mem;
int *p0,*p1,*p2;

work_mem = malloc ( 3* N_ELEM * sizeof *work_mem);
if (!work_mem) { OMG(); return; }

p0 = work_mem, p1= work_mem + N_ELEM, p2 = work_mem + 2 * N_ELEM;

        /* do useful stuff here with work_mem
        ** , possibly via p0,p1,p2
         */

free(work_mem);
}

另一种方法是将所有需要的内存分配到一个大内存块中, 并将其部分视为p0,p1,p2:

void worker(void)
{
#define N_ELEM 123
int *work_mem;
int *p0,*p1,*p2;

work_mem = malloc ( 3* N_ELEM * sizeof *work_mem);
if (!work_mem) { OMG(); return; }

p0 = work_mem, p1= work_mem + N_ELEM, p2 = work_mem + 2 * N_ELEM;

        /* do useful stuff here with work_mem
        ** , possibly via p0,p1,p2
         */

free(work_mem);
}


将它们放在一个以NULL结尾/初始化的数组中,并迭代该数组。我希望除了使用数组之外,还有另一种方法可以做到这一点。
ptr1*=malloc(1)完全是胡说八道。请发布真实代码。@joop这是怎么回事?假设ptr1、ptr2和ptr3是全局变量。@SirDrinksCoffeeALot我希望有另外一种方法来实现这一点,除了使用数组:不,没有。将它们放在以NULL结尾/初始化的数组中,并迭代该数组。我希望有另外一种方法来实现这一点,除了使用数组。
ptr1*=malloc(1)完全是胡说八道。请发布真实代码。@joop这是怎么回事?假设ptr1、ptr2和ptr3是全局变量。@SirDrinksCoffeeALot我希望有另外一种方法可以做到这一点,除了使用数组:没有。@user694733,这将使代码依赖于
free
的行为(实现)来避免释放空指针时崩溃。我同意在调用free之前测试ptr是否为NULL的原始、防御性和正确的方法。@PaulOgilvie C standard(来自草案N1570)第7.22.3.3章说:“free函数导致ptr指向的空间被释放,也就是说,可供进一步分配。如果ptr是NULL指针,则不会发生任何操作……”@user694733,标准改变。过去的标准没有这个。代码不是防御性的。它可能导致不必要的函数调用。我的论点可能是基于观点的。@PaulOgilvie标准完全改变了。因此,在释放之前,不需要遵守arhaic规则并检查NULL。(free的定义是这样的,至少是因为(包括)c89和on)是的,但是如果您的malloc在ptr2上失败,那么您将转到end并尝试释放尚未分配的ptr2和ptr3,并且您将在尝试释放未分配的内存时出错?@user694733,这将使代码依赖于行为(实现)释放空指针时不会崩溃。我同意在调用free之前测试ptr是否为NULL的原始、防御性和正确的方法。@PaulOgilvie C standard(来自草案N1570)第7.22.3.3章说:“free函数导致ptr指向的空间被释放,也就是说,可供进一步分配。如果ptr是NULL指针,则不会发生任何操作……”@user694733,标准改变。过去的标准没有这个。代码不是防御性的。它可能导致不必要的函数调用。我的论点可能是基于观点的。@PaulOgilvie标准完全改变了。因此,在释放之前,不需要遵守arhaic规则并检查NULL。(free的定义是这样的,至少是因为(包括)c89和on)是的,但是如果您的malloc在ptr2上失败,那么您将转到end并尝试释放尚未分配的ptr2和ptr3,并且您将在尝试释放未分配内存时出错?虽然这可以工作,但您必须手动确保所有指针都正确对齐。将所有变量放在单一结构中会更安全,并让编译器整理对齐细节。是的,但您也必须注意原始情况下的正确性。[例如,(更正)问题中的
int*p=malloc(1);
甚至不适合存储单个int]True,但这是大小问题,而不是对齐问题。但即使使用struct也更容易处理大小问题,假设所需的大小是静态的,如示例中所示:
CombinedType*data=malloc(sizeof*data)基本上,大小和对齐是同一事物的两种表现形式。(在实践中,
sizeof
是您的朋友)我并不是给出所有问题的通用解决方案,只是一个在某些情况下可能有用的代码模式。它不是通用解决方案,这就是为什么应该对可能的对齐问题发出警告。当使用混合类型时,初学者可能不知道为什么
malloc(3)
对于他的
uint8\u t*p0,uint16\u t*p1是不够的在普通系统上。虽然这可以工作,但您必须手动确保所有指针都正确对齐。将所有变量放在单一结构中会更安全,并让编译器整理对齐细节。是的,但您也必须注意原始情况下的正确性。[问题(已更正)中的
int*p=malloc(1);
将不会被删除