【问题标题】:Changed memory address using realloc in C在 C 中使用 realloc 更改内存地址
【发布时间】:2018-05-31 19:58:28
【问题描述】:

我确实对 C 中的内存重新分配有疑问,因为我认为这导致了一个问题,我已经有一个星期了,但没有找到它。 我是你有正方形的纸,你的人用绿色填充了几个正方形。所以现在,我正在尝试读取绿色方块的坐标(有人将它们放入标准输入),然后我想通过查看它们是否相邻来将它们链接在一起。 所以在 Cell 结构中,所有的 Cell 都有坐标、指向潜在邻居的指针和邻居计数器。还有一个名为 setNeighbours 的函数,它判断它们是否是邻居并将地址填充到每个对象中。 所以我的问题是关于重新分配方法,因为我知道这可能会将地址块移动到其他地方,因此,有时(可能 40% 的时间)我在打印结果时会得到错误的结果。

代码如下。 我知道重新分配行是原因,因为如果我删除它并在 malloc 行中放入足够的空间,以便以后不需要重新分配,那么一切正常。 我想有一个愚蠢的时刻,我要求一个以前更改过的旧地址,但我看不到它。有人看到了吗?

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>

typedef struct Square {
    long index;
    long x;
    long y;
    struct Square *Above;
    struct Square *Below;
    struct Square *Right;
    struct Square *Left;
    int count;
} SquareType;

SquareType *cellArr;
long countSquares = 0;

示例输入:

1 3
2 3
3 3
2 2
2 1
3 2

【问题讨论】:

  • 为什么不在proofString() 中使用sscanf("%d %d")
  • 调用setNeighbours()的循环应该在你读完所有坐标之后执行一次,而不是在读完每一行之后。
  • 如果你这样做,所有的重新分配将首先完成,你不会有任何指向旧地址的悬空指针。
  • 使用索引(数组的偏移量)而不是指针。
  • 为什么要使用全局变量?养成的坏习惯

标签: c realloc


【解决方案1】:

所以我的问题是关于重新分配方法,因为我知道这是 可能将地址块移动到其他地方并且是合理的 为此,有时(可能是 40% 的时间)我错了 打印出结果时的结果。

确实,realloc() 并不总是将重新分配的块放在与原始块相同的地址。如果重新分配包含结构的空间,则必须假设在重新分配之前获得的指向这些结构的任何指针都不再有效。您的代码似乎没有做出这种假设。

只有几个可行的解决方案:

  • 不要依赖指向分配空间的指针,除了你维护到空间开头的主要指针。实现这一点的一种方法是通过索引而不是直接指向它们的指针来识别邻居。或者,

  • 只有在读取所有数据后才设置指针,这样您就可以确定所有需要的重新分配都已执行。或者,

    • 特殊情况:只要数据重新分配到不同的地址,就重新计算所有指针。或者,
  • 避免重新分配。您可以通过预先为所有内容分配足够的空间来做到这一点(如果您拥有或至少可以获得所需数量的合理上限,这是一个非常好的选择),或者通过独立于其他结构分配每个结构。

【讨论】:

  • 不是他的问题,也是不好的建议。 realloc() 函数对于开发动态大小的对象来说是一个非常好的和有用的函数; “避免它”不是有用的建议。此外,他在这里正确使用它,改变了他的指针。
  • @LeeDanielCrocker 在重新分配之后,之前的setNeighbours() 需要重新完成,或者只是推迟到所有读取完成。我会说约翰在这里是关于重新分配不足的。 realloc() 可以,setNeighbours() 位置不行。
  • 也许你读得太快了,@LeeDanielCrocker。我从来没有声称不应使用realloc()一般,而是必须假定重新分配内存块会使指向原始块的现有指针无效。必须避免或处理它,我提供了两种选择。是的,OP 正在更改他指向块的指针,但是 其中的数据 包含彼此的指针,并且这些指针没有被更新。
  • 是的,这是有道理的,谢谢。如果您要使用 realloc() 创建一个不断增长的结构,请确保正在增长的(可能是移动的)部分内的东西只指向正在增长的部分之外的东西。
猜你喜欢
  • 2015-08-22
  • 2020-11-20
  • 2018-03-27
  • 1970-01-01
  • 1970-01-01
  • 2013-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多