【发布时间】:2012-12-05 23:12:46
【问题描述】:
我有以下代码,它只是打印出一个人名的介绍。
#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;
}
产生输出
The person you are looking for is Bob Newmonson
但是将intro(a) 更改为intro(&a) 会产生
The person you are looking for is �@ Newmonson
当我在 GDB 中打开第一次尝试并在第 10 行中断时,我找到了person=0x601010 的地址。名字和姓氏都存储在我期望的位置,0x04006b9 和 0x4006bd,因为它们在堆栈中较早声明的位置。
当我使用对intro(&a) 所做的更改运行 GDB 时,我得到了启发。 person的地址现在是0x7fffffffffdd38,名字指向0x601010,姓氏指向0x4006db。
谁能帮忙解释一下发生了什么以及为什么我仍然可以在第二次测试中访问姓氏的正确地址。
编辑:
正如每个人似乎一直在问这个问题,void * 用于此代码的线程部分,我没有包括在内。
【问题讨论】:
-
仅供参考:
first = (char *)malloc(sizeof(char)*20); first = "Bob";没有做你认为它正在做的事情。 -
另外,你为什么要声明
intro()使用void*,而唯一有希望使用它的是Person*? -
@MichaelBurr 我想和
void*一起练习,结果却遇到了这个问题。 -
将 person 转换为 int 并打印出来。您将看到指针保存的值。它应该是您之前看到的十六进制值。
-
@TimCooper 一开始我并没有想到你在说什么,但后来我突然意识到我的 malloc 正在被堆栈上完全覆盖
Bob和Newmanson而不是使用strncpy将我想要的内容复制到分配的内存中。