C中指针的自由函数问题

Problem with free function in C for pointers

我有两个指针,我想用指针v.

中包含的值填充指针somme

这是方法:

somme[0]=v[0] + v[1];
somme[1]=v[2] + v[3];
somme[2]=v[4] + v[5];

...

执行distruggi_vec(somme);函数时出现错误,而不是distruggi_vec(v);

你有什么想法吗?谢谢你的时间。

这是我的 C 代码:

#include <stdlib.h>
#include <stdint.h>

extern uint32_t *crea_vec(size_t  n)
{
    uint32_t *p;
    p = malloc(n * sizeof(uint32_t));
    for (size_t i = 0; i < n; ++i)
    {
        p[i] = i;
    }

    return p;
}

uint32_t *somme_2a2(uint32_t *vett, size_t size) 
{
    if (size % 2 != 0) 
    {
        size = size - 1;
    }

    size_t j = 0;
    for (size_t i = 0; i < size; ++i) 
    {
        if (i >= 10) { goto a; }
        j = i * 2;
        vett[i] = vett[j] + vett[j + 1];
    }
    a:
    size = size / 2;
    vett = realloc(vett, size * sizeof(uint32_t));

    return vett;
}

extern void distruggi_vec(uint32_t *p)
{
    free(p);
}

int main(void) 
{
    size_t n = 20;
    uint32_t *v = crea_vec(n);
    uint32_t *somme = somme_2a2(v, n);
    distruggi_vec(v);
    distruggi_vec(somme);

    return 0;
}

当我调试我的代码时,出现了这个问题:

首先,不要写这样的代码

 vett = realloc(vett, size * sizeof(uint32_t));

如果 realloc() 失败,您也会丢失原始指针。

来自 C11,章节 §7.22.3.5

If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged.

The realloc function returns a pointer to the new object (which may have the same value as a pointer to the old object), or a null pointer if the new object could not be allocated.

始终在临时指针中捕获 realloc() 的 return 值,对照 NULL 进行检查,如果有效,您可以(可选)将其分配回原始指针指针。像(伪代码)

pointer temp = NULL;
temp = realloc (oldPOinter, size);
if (!temp) 
{
    printf ("Some error message");
    return SOME_ERROR_CODE;
}
oldPOinter = temp;

也就是说,这里的问题是,万一realloc()成功了,原来的指针就不能再用了。 v 作为参数传递给 somme_2a2(),并且根据 C,它是按值传递的。因此,对 vett 所做的任何更改都不会反映到 v.

中的调用者

但是,由于 realloc() 将内存指针的有效性更改为 vett,在 return 从 somme_2a2() 调用成功后,在 main(), v 不再有效,您不需要将其传递给 free().

引用 C11,章节 §7.22.3.5

The realloc function deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by size. [...]

vett 传递给 free() 将导致未定义的行为,因为您最终会尝试 free() 一个已经 free()-d [via realloc()] 的成功。

引用章节 §7.22.3.3

[...] if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.

不管你对 realloc 调用多少次,你仍然只有 一个 指针:第一个 lastmalloccallocrealloc.

返回

调用realloc后原指针失效,只能使用returns.

这意味着当您使用无效指针 v 调用 distruggi_vec 时,您将得到 undefined behavior.

谢谢大家的宝贵时间,这是我的问题的最终解决方案,没有错误:

代码:

`

#include <stdlib.h>
#include <stdint.h>

extern uint32_t *crea_vec(size_t  n)
{
    uint32_t *p;
    p = malloc(n * sizeof(uint32_t));
    for (size_t i = 0; i < n; ++i)
    {
        p[i] = i;
    }

    return p;
}

uint32_t *somme_2a2(uint32_t *vett, size_t size) 
{
    uint32_t *vett2 = calloc(size/2, sizeof(uint32_t));
    if (size % 2 != 0) 
    {
        size = size - 1;
    }

    size_t j = 0;
    for (size_t i = 0; i < size; ++i) 
    {
        if (i >= 10) { break; }
        j = i * 2;
        vett[i] = vett[j] + vett[j + 1];
        vett2[i] = vett[i];
    }

    return vett2;
}

extern void distruggi_vec(uint32_t *p)
{
    free(p);
}

int main(void) 
{
    size_t n = 20;
    uint32_t *v = crea_vec(n);
    uint32_t *somme = somme_2a2(v, n);
    distruggi_vec(v);
    distruggi_vec(somme);

    return 0;
}

`