我有以下代码,它只是打印出一个人名的介绍。
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char* firstname;
char* lastname;
}Person;
void intro(void *person){
printf("The person you are looking for is %s %s\n", ((Person *)person)->firstname, ((Person *)person)->lastname);
}
int main()
{
Person *a = NULL;
a = (Person *)malloc(sizeof(Person));
char *first = NULL, *last = NULL;
first = (char *)malloc(sizeof(char)*20);
strncpy(first,"Bob", 20);
last = (char *)malloc(sizeof(char)*20);
strncpy(last,"Newmonson", 20)
a->firstname = first;
a->lastname = last;
intro(a);
return 0;
}
产生输出
您要找的人是 Bob Newmonson
但是将 intro(a)
更改为 intro(&a)
会产生
你要找的人是�@Newmonson
当我在 GDB 中打开第一次尝试并在第 10 行中断时,我找到了 person=0x601010
的地址。名字和姓氏都存储在我期望的位置,0x04006b9
和 0x4006bd
因为它们在堆栈中较早的位置声明。
让我着迷的是当我运行 GDB 并对 intro(&a)
进行更改时。 person
的地址现在是 0x7fffffffffdd38
,名字指向 0x601010
,姓氏指向 0x4006db
.
谁能帮忙解释一下这是怎么回事,为什么我在第二次测试中仍然可以访问姓氏的正确地址。
编辑:
因为每个人似乎都在问这个问题,void *
是我没有包含的这段代码的线程部分。
最佳答案
因为a
已经是指向Person
结构的指针;因此 intro(&a)
将指针传递给该指针,但 intro()
将其参数视为指向 Person
的指针。
此外,如果 intro()
打算作用于 Person,它应该声明一个 Person *
参数,而不是 void *
.
关于C 指针引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13715649/