[英]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
的新对象的指针。 [...]
传递vett
到free()
将导致未定义的行为,因为你最终会试图free()
这已经是一个指针free()
-d [通过成功realloc()
]。
引用第§7.22.3.3章
[...]如果参数与内存管理函数先前返回的指针不匹配,或者如果通过调用
free
或realloc
释放了空间,则该行为未定义。
不管您进行多少次realloc
调用,您仍然只有一个指针: 最后一个由malloc
, calloc
或realloc
返回。
通话结束后,以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.