繁体   English   中英

问题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(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节

如果无法分配用于新对象的内存,则不会释放旧对象,并且其值不变。

realloc函数返回指向新对象的指针(该值可能与指向旧对象的指针的值相同),如果无法分配新对象,则返回空指针。

始终在临时指针中捕获realloc()的返回值,针对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 ,从成功返回后somme_2a2()调用,在main()v是不再有效,而你并不需要传递到free()

引用C11 ,第§7.22.3.5章

realloc函数取消分配ptr指向的旧对象,并返回一个指向具有size指定size的新对象的指针。 [...]

传递vettfree()将导致未定义的行为,因为你最终会试图free()这已经是一个指针free() -d [通过成功realloc() ]。

引用第§7.22.3.3章

[...]如果参数与内存管理函数先前返回的指针不匹配,或者如果通过调用freerealloc释放了空间,则该行为未定义。

不管您进行多少次realloc调用,您仍然只有一个指针: 最后一个malloccallocrealloc返回。

通话结束后,以realloc原来的指针变为无效,你应该只使用它返回的指针。

这意味着当您使用无效指针v调用distruggi_vec ,将具有未定义的行为

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

码:

`

#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;
}

`

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM