我试图了解为什么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;
编译器输出如下所示(显然,每次运行时内存地址都会更改):
信息:sfIntRect是四个合并的整数值。
我在这里注意到的是,从我在realloc上阅读的所有内容来看,它似乎可以正常工作,因为new_frames返回与base_frames相同的原始地址,并且块的大小增加了。该块的添加未初始化,因此我希望这些构造的值古怪,它们是。但是,前十个分配不应妥协,看起来好像其中两个分配一样。每次运行时都使用相同的元素。
有人可以帮忙阐明一下吗?
答案 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
之后才使用空格,并且函数调用仅在,
分隔参数之后才有空格。