重新分配损坏的源内存

时间:2019-03-03 15:13:49

标签: c malloc

我试图了解为什么realloc似乎破坏了我正在扩展的内存源块。我没有排除代码中某些内容不正确的可能性。该代码使用的是C SFML中的构造。

sfUint16* num_frames = malloc (sizeof (sfUint16)); if (NULL == num_frames) exit (-1);
(*num_frames) = 10;
printf ("num_frames address: %p\n", num_frames);
printf ("num_frames value: %i\n", (*num_frames));

sfIntRect* base_frames = malloc ((*num_frames) * sizeof (sfIntRect)); if (NULL == base_frames) exit (-1);
printf ("base_frames address: %p\n", base_frames);
for (int a = 0; a < (*num_frames); a++) {
    base_frames [a].top = 10;
    base_frames [a].left = 10;
    base_frames [a].width = 50;
    base_frames [a].height = 100;
    printf ("base_frames allocation %i: %i, %i, %i, %i\n", a, base_frames [a].top, base_frames [a].left, base_frames [a].width, base_frames [a].height);
}

sfIntRect* sample_frame = malloc (sizeof (sfIntRect)); if (NULL == sample_frame) exit (-1);
sample_frame->top = 20;
sample_frame->left = 20;
sample_frame->width = 200;
sample_frame->height = 300;
printf ("sample_frame address: %p\n", sample_frame);
printf ("base_frames[5] preassignment: %i, %i, %i, %i\n", base_frames [5].top, base_frames [5].left, base_frames [5].width, base_frames [5].height);
base_frames [5] = (*sample_frame);
printf ("base_frames[5] postassignment: %i, %i, %i, %i\n", base_frames [5].top, base_frames [5].left, base_frames [5].width, base_frames [5].height);
free (sample_frame);
printf ("base_frames[5] postfree of sample_frame: %i, %i, %i, %i\n", base_frames [5].top, base_frames [5].left, base_frames [5].width, base_frames [5].height);

sfIntRect* new_frames = realloc (base_frames, (*num_frames) * 2);
if (new_frames) base_frames = new_frames;
else free (new_frames);
printf ("address of base_frames: %p\n", base_frames);
for (int a = 0; a < (*num_frames) * 2; a++) {
    printf ("base_frames allocation %i: %i, %i, %i, %i\n", a, base_frames [a].top, base_frames [a].left, base_frames [a].width, base_frames [a].height);
}

free (num_frames);
free (base_frames);

return 0;

编译器输出如下所示(显然,每次运行时内存地址都会更改):

Program Output

信息:sfIntRect是四个合并的整数值。

我在这里注意到的是,从我在realloc上阅读的所有内容来看,它似乎可以正常工作,因为new_frames返回与base_frames相同的原始地址,并且块的大小增加了。该块的添加未初始化,因此我希望这些构造的值古怪,它们是。但是,前十个分配不应妥协,看起来好像其中两个分配一样。每次运行时都使用相同的元素。

有人可以帮忙阐明一下吗?

1 个答案:

答案 0 :(得分:3)

替换

... = realloc(... , (*num_frames) * 2);

针对:

... = realloc(..., (*num_frames) * 2 * sizeof(sfIntRect));

您不想分配(*num_frames) * 2字节,而是想要分配(*num_frames) * 2个“帧”,其中一帧具有sizoef(sfIntRect)个字节。如果重新分配成功(假设为printf,则在接下来的sizeof(sfIntRect) > 1中访问的内存无效。

else free (new_frames);之后的if (new_frames)看起来毫无意义,new_frames == NULL毫无意义。

我想我必须主观地在函数调用后标记空格。 printf (...)free (...)realloc (..)和使用[]运算符之前的空格对我来说似乎不可读。而且,很长的行也不可读。我更喜欢使用语法,其中仅在条件构造if while for之后才使用空格,并且函数调用仅在,分隔参数之后才有空格。