typedef结构的malloc/realloc的正确用法
我有一个功能齐全的程序*,但我确实有一个关于分配内存的问题,因为有些东西对我来说还不清楚。(*完全功能性意味着,它有我想要的结果,这也可能是运气) 有两个结构,一个叫做Cell,一个叫做Stone,这个单元有坐标,一个索引,一个计数,一个bool和指向其他四个单元的指针。 石头只有两个指向细胞的指针。两者都是为同一个名称定义的typedef,只是附加了Td 所以我的问题是为它分配内存。 对于第一个malloc,我将使用以下四条语句,然后再附加更多元素 这就是我学习它的方式,我想a也可以用“结构单元”来代替“CellTd”等等。x只是谈论我问题的一个因素 我现在的问题是,我不确定这是否绝对正确,因为当增加x时,我有不同的结果。因此,当我使用它时,当因子x为1时,有时没有指向某些元素的严肃指针。我使用x=50,然后一切都正常,但这不应该是,它是如何工作的。(当然,countStones和countCells在创建时也会使用数组中的元素数…)typedef结构的malloc/realloc的正确用法,c,struct,typedef,realloc,C,Struct,Typedef,Realloc,我有一个功能齐全的程序*,但我确实有一个关于分配内存的问题,因为有些东西对我来说还不清楚。(*完全功能性意味着,它有我想要的结果,这也可能是运气) 有两个结构,一个叫做Cell,一个叫做Stone,这个单元有坐标,一个索引,一个计数,一个bool和指向其他四个单元的指针。 石头只有两个指向细胞的指针。两者都是为同一个名称定义的typedef,只是附加了Td 所以我的问题是为它分配内存。 对于第一个malloc,我将使用以下四条语句,然后再附加更多元素 这就是我学习它的方式,我想a也可以用“结构单
我在重新分配方面做错了什么?首先,如果您想分配一组东西,请使用。它检查乘法溢出,并用零很好地初始化所有值 其次,确保您正在检查
calloc
和realloc
调用是否成功。如果失败,它们将返回空指针。然后您可以使用来确定它们失败的原因,打印漂亮的错误消息,然后退出
对于您的逻辑,下面是一个快速gdb会话使用最小代码发现的内容(我只将第75行的I
类型更改为unsigned int
):
在故障点:
(gdb) bt
#0 0x0000000000401112 in evaluateNeighbourNum (original=0x6034b0)
at cells.c:153
#1 0x0000000000401350 in evaluateNeighbourNum (original=0x612f20)
at cells.c:201
#2 0x0000000000401509 in calculate () at cells.c:229
#3 0x00000000004016c8 in main () at cells.c:250
(gdb) p *original
$14 = {
index = 2,
x = 1,
y = 0,
N = 0x411,
S = 0x6e20666f206d754e,
E = 0x72756f6268676965,
W = 0x2029302c31282073,
count = 925966394,
used = 48
}
如您所见,
N
正在被垃圾填充(0x411不是有效指针)。看看您是如何填充节点的。这四行malloc
/realloc
调用是否如图所示相邻,或者中间是否有come代码。您可以使用注释(如/*…)指示中间有代码*/代码>(或/*…*/
,如果您愿意的话)。符号ptr=realloc(ptr,newsize)代码>本身就是危险的。如果realloc()
失败,它将返回一个空指针,这意味着您泄漏了内存,因为您用空指针覆盖了指向内存的上一个指针。您需要使用void*newptr=realloc(ptr,newsize);如果(newptr==NULL){…句柄错误…}ptr=newptr代码>。您的struct Cell
包含四个指向struct Field
的指针,而不是如您的注释所示的struct Cell
?这是翻译问题吗?您可以使用sizeof(CellTd)
使用malloc()
;使用sizeof(FieldTd)
,您可以使用realloc()
;其中一个是错误的——可能两者都是。类似地,对于StoneTd
和FlagstoneTd
。使用cerlar=malloc(x*sizeof(cerlar[0])是明智的代码>或cerlar=malloc(x*sizeof(*cerlar))代码>。这避免了更改类型名称的问题。“增加x时的不同结果”后面的文本不清楚。请给出一个例子,最好是以“输入”和“输出”的形式。你所说的“结果”到底是什么意思?它是由一些不相关的代码计算的值吗?此外,“一切正常”等短语通常需要澄清。另见。是的。刚刚也纠正了这一点。很抱歉,上次编辑后应该重新阅读!现在它应该完全准备好了。谢谢你关于处理内存泄漏的想法,我刚刚在主题中添加了这一点。如果所有for指针都为NULL,而它们所指向的实际元素都为NULL,那么sizeof(CellTd)是否可能在不同的情况下有所不同?如果是,那么这应该是问题的结果。我只是通过处理可能的重新分配问题来更新代码。我也理解你对calloc的想法,但我现在并没有为了这个话题而改变它。谢谢你的回答。我不确定我是否真的同意calloc
的建议。这就对内核施加了额外的限制,以分配归零的内存,因此成本更高calloc
在某些情况下是一个不错的选择,但我不同意“如果你想分配一系列的东西”,这总是一个好办法。@cadaniluk这听起来像是过早的优化。我宁愿依靠标准库来检查乘法溢出,也不愿自己去做。如果在剖析之后,CALLC调用被证明是执行时间的一个重要部分,我会考虑替换它。对我来说,这不是关于优化。我只是反对calloc
,而不是支持malloc
malloc
只是为我分配内存的标准库调用calloc
用于特殊用途。因此,我不会像那样默认为calloc
。如果有什么不同的话,我会介绍一些类似于#define ALLOC_MEM
的东西,并使用malloc
或calloc
实现该宏,具体取决于我是在调试还是在编写发布代码。生产代码到此为止;在这个简单的例子中,calloc
是可以的,但我并不认为一般来说它比malloc
好。@cadaniluk我不是说总是在分配数组时使用calloc
而不是malloc
,以避免函数调用中的乘法。
(gdb) bt
#0 0x0000000000401112 in evaluateNeighbourNum (original=0x6034b0)
at cells.c:153
#1 0x0000000000401350 in evaluateNeighbourNum (original=0x612f20)
at cells.c:201
#2 0x0000000000401509 in calculate () at cells.c:229
#3 0x00000000004016c8 in main () at cells.c:250
(gdb) p *original
$14 = {
index = 2,
x = 1,
y = 0,
N = 0x411,
S = 0x6e20666f206d754e,
E = 0x72756f6268676965,
W = 0x2029302c31282073,
count = 925966394,
used = 48
}