Wit*_*ion 2 c arrays struct gdb garbage
将值放入我的数组后,一步之后(感谢gdp)数组包含垃圾.之后的唯一步骤是将参数传递给函数:
struct Vertex;
typedef struct Vertex Vertex;
struct Vertex {
int sides[2][LENGTH];
int ends[2];
Vertex *children;
Vertex *parent;
};
void move(Vertex *node, int side, int place) {
(38) int handfull = (*node).sides[side][place];
.....
}
int blah(Vertex *node, int side) {
.....
(103) *((*node).children + i) = init_child(node);
(104) move((*node).children + i, side, i);
(105) blah((*node).children + i, opposingside);
.....
}
Run Code Online (Sandbox Code Playgroud)
gdb告诉我以下内容:
(gdb) print (*node)
$7 = {sides = {{5, 5}, {0, 5}}, ends = {0, 1},
children = 0x7fffffffdfa0, parent = 0x7fffffffe110}
(gdb) print node
$8 = (Vertex *) 0x7fffffffe0c0
(gdb) print ((*node).children + i)
$9 = (Vertex *) 0x7fffffffdfa0
(gdb) print *((*node).children + i)
$10 = {sides = {{5, 5}, {0, 5}}, ends = {0, 1},
children = 0x7fffffffdf20, parent = 0x7fffffffe0c0}
(gdb) step
move (node=0x7fffffffdfa0, place=0, side=0) at mancala.c:38
38 int handfull = (*node).sides[side][place];
(gdb) print node
$11 = (Vertex *) 0x7fffffffdfa0
(gdb) print (*node)
$12 = {sides = {{-8160, 32767}, {4196818, 0}}, ends = {0, 1},
children = 0x7fffffffdf20, parent = 0x7fffffffe0c0}
Run Code Online (Sandbox Code Playgroud)
我在第104行(称为move)中断.之后,(*node).children + i指向Vertex结构,由$ 9和$ 10证明.我向move功能迈出了一步.这应该将我的顶点地址,返回地址等推入堆栈并开始在move函数中工作.看看11美元,我们看到顶点地址与9美元相同,这很好.然而,在12美元,阵列.sides现在充满了垃圾.其他一切都很好,但只是那个阵列充满了垃圾.
这是怎么一步发生的?我不能一次调试任何一步,所以我现在不知道该怎么做.
编辑:这是init_child函数:
Vertex init_child(Vertex *node) {
Vertex children[LENGTH];
int i;
int j;
Vertex child = (*node);
for (j = 0; j < 2; j++) {
for (i = 0; i < LENGTH; i++)
child.sides[j][i] = (*node).sides[j][i];
child.ends[j] = (*node).ends[j];
}
child.children = children;
child.parent = node;
return child;
}
Run Code Online (Sandbox Code Playgroud)
这是初始化第一个Vertex的main()函数:
int main(int argc, char **argv) {
Vertex children[LENGTH];
Vertex head = {.sides = {{4,4}, {4,4}}, .ends = {0}, .children = children, .parent = NULL};
blah(&head, 1);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
问题是使用在函数范围创建的数组的地址进行init_child()初始化children.当函数返回时,数组不再有效,因此返回的子结构指向无效对象.
Vertex init_child(Vertex *node) {
Vertex children[LENGTH]; /* array variable on the stack */
/*...*/
child.children = children; /* child pointing to local variable */
child.parent = node;
return child;
}
Run Code Online (Sandbox Code Playgroud)
相反,例程应该动态分配内存,以便子进程指向内存,并在函数返回后继续存活.
Vertex init_child(Vertex *node) {
/*...*/
child.children = malloc(LENGTH*sizeof(*child.children));
child.parent = node;
return child;
}
Run Code Online (Sandbox Code Playgroud)