我有两个指针,我想用指针somme
中包含的值填充指针v
。
这是方法:
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;
}
当我调试代码时,它给了我这个问题:
答案 0 :(得分:3)
首先,不要像这样写代码
vett = realloc(vett, size * sizeof(uint32_t));
如果realloc()
失败,您也将丢失原始指针。
从C11
的第7.22.3.5章起
如果不能为新对象存储 分配后,旧对象不会被释放,其值保持不变。
和
realloc
函数返回一个指向新对象的指针(该对象可能具有相同的指针 值作为指向旧对象的指针),如果新对象不能为null,则返回null指针 已分配。
始终在临时指针中捕获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
中,{{1 }}不再有效,您无需将其传递给free()
。
引用C11
,第7.22.3.5章
realloc
函数释放由ptr
指向的旧对象,并返回一个 指向具有size
指定大小的新对象的指针。 [...]
将vett
传递给free()
会引起不确定的行为,因为您最终将尝试free()
-d的指针[{ free()
]。
引用第7.22.3.3节
[...]如果 该参数与内存管理器先前返回的指针不匹配 函数,或者如果通过调用
realloc()
或free
释放了空间,则 行为是不确定的。
答案 1 :(得分:1)
您对realloc
的调用次数无关紧要,您仍然只有一个指针:{{1 }},malloc
或calloc
。
在调用realloc
之后,原始指针将变为无效,您只能使用它返回的指针。
这意味着当您使用无效的指针realloc
调用distruggi_vec
时,您将拥有undefined behavior。
答案 2 :(得分:1)
谢谢您的时间,这是我的问题的最终解决方案,没有错误:
代码:
`
#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;
}
`