好的,所以我对c中的结构都是全新的,我有一个对我来说很奇怪的问题。
当使用它的指针将一个简单的结构传递给一个函数时,该结构会自动将该函数的其他参数之一作为它的新数据。我不知道为什么会发生这种情况..
此时move_walker()应该什么都不做,对吧?
typedef struct {
int x,
y;
} walker_t;
walker_t* init_walker(int x, int y) {
walker_t walker;
walker.x = x;
walker.y = y;
walker_t *pointer = malloc(sizeof(walker));
pointer = &walker;
return pointer;
}
int move_walker(walker_t * walker, int direction) {
return 0;
}
walker_t* walker;
walker = init_walker(8,2);
printf("%d %d\n", walker->x, walker->y); //will print '8 2'
move_walker(walker, 3);
printf("%d %d\n", walker->x, walker->y); //will print '0 3'
(我很确定它并不重要,但这段代码实际上是在多个文件上传播的。)
答案 0 :(得分:3)
您的init_walker
错误,因为它返回指向堆栈局部变量walker
的指针。 init_walker
退出后,该变量的内存将被回收。您的第一个printf
仍然可以正常工作,因为您的walker
变量的值在堆栈中仍未触及。但是,只要在此之后进行任何函数调用,原始init_walker
调用的堆栈帧就会被覆盖,而walker
指针现在指向一些随机垃圾。
当您malloc
内init_walker
时,您已经在堆上分配内存(与堆栈不同,它超出了堆栈帧的生命周期)walker_t
。所以,你应该这样做:
walker_t* init_walker(int x, int y) {
walker_t *pointer = malloc(sizeof(walker_t));
pointer->x = x;
pointer->y = y;
return pointer;
}
答案 1 :(得分:3)
问题是你的walker
指针转到了无效的堆栈内存,因为init_walker
有一个错误:你在堆栈上创建一个walker_t
结构,然后使用{{1保留内存并将该内存的地址分配给malloc
。到目前为止一切都很好。
但是,行pointer
不将结构从堆栈复制到新内存,而是使pointer = &walker
指向堆栈上的结构! pointer
是&walker
的地址,您可以将其指定给指针。你可能想要做的是复制结构。要做到这一点,你必须取消引用你的指针:
walker
这应该使您的程序按预期工作。您也可以完全跳过堆栈上的结构:
*pointer = walker
答案 2 :(得分:2)
您正在堆栈上创建struct-object。您需要使用
分配它walker_t* init_walker(int x, int y) {
walker_t* walker = malloc(sizeof(walker_t));
...
return walker;
}
使用
walker_t *pointer = malloc(sizeof(walker));
pointer = &walker;
你正在创造一个内存泄漏!将新内存分配给*指针并在将& walker指定给指针时丢失指针。
答案 3 :(得分:0)
walker_t* init_walker(int x, int y) {
walker_t walker;
walker.x = x;
walker.y = y;
walker_t *pointer = malloc(sizeof(walker));
*pointer = walker; /* here was the error. Copy the value not the adress */
return pointer;
}
但它可以更简单:
walker_t* init_walker(int x, int y) {
walker_t *pointer = malloc(sizeof(*pointer));
pointer->x = x;
pointer->y = y;
return pointer;
}
答案 4 :(得分:0)
你的代码就是把政治变得“非常奇怪”。
这会更好......
walker_t *init_walker (int x, int y)
{
walker_t *p_walker = (walker_t *)malloc (sizeof(walker));
if (p_walker != NULL)
{
p_walker->x = x;
p_walker->y = y;
}
return (p_walker);
}
然后在完成后调用free (walker)
答案 5 :(得分:0)
......或者,在对代码进行完整性检查之后,您还可以写下:
typedef struct
{
int x,
int y;
} walker_t;
void init_walker(walker_t* obj, int x, int y)
{
obj->x = x;
obj->y = y;
}
walker_t walker;
init_walker(&walker, 8,2);