此程序返回指向结构的指针
当我打印内容时,名称未正确显示,其他两个变量正在正确打印。
可能是什么问题呢?
这是C
#include<stdio.h>
struct student
{
char name[20];
int marks;
int rank;
};
struct student stu;
struct student *create();
void main()
{
struct student *ptr;
ptr = create();
printf("%s\t %d\t %d\t",ptr->name,ptr->marks,ptr->rank);
}
struct student *create()
{
struct student stu = {"john",98,9};
struct student *ptrr;
ptrr = &stu;
return ptrr;
}
答案 0 :(得分:6)
这里的问题是您返回指向本地变量的指针。一旦返回定义函数,局部变量就会超出范围。这意味着您返回的指针将在函数返回后指向未分配的内存。使用该指针将导致undefined behavior。
有三种方法可以解决这个问题:
static
局部变量。它的生命周期也与程序相同。第1点和第2点有一个问题,那就是你只能有一个对象。如果修改该对象,则所有具有指向该单个对象的指针的位置都将看到这些更改。
第3点是我建议你去的方式。问题在于,一旦你完成了对象,就必须释放你分配的内存。
答案 1 :(得分:1)
您创建一个位于函数stu
中的局部变量create()
。在函数create()
之外,此变量上的指针不正确。
答案 2 :(得分:1)
作为Joachim Pileborg answered,您不应该返回指向局部变量的指针。顺便说一句,如果使用gcc -Wall -g
编译最近的GCC(例如启用几乎所有警告和调试信息),您应该收到警告。
所以在实践中,你应该决定你的create
返回一个堆指针,然后采用约定它的调用者释放该指针。
void main() {
struct student *ptr;
ptr = create();
printf("%s\t %d\t %d\t",ptr->name,ptr->marks,ptr->rank);
free (ptr);
}
struct student *create() {
struct student stu = {"john",98,9};
struct student *ptrr = malloc(sizeof struct student);
if (!ptrr) { perror("malloc student"); exit(EXIT_FAILURE); }
*ptrr = stu;
return ptrr;
}
仔细阅读C dynamic memory allocation,manual memory management,heap,memory leaks和malloc(3)手册页上的wikipages。如果您有幸在Linux上编码,请了解valgrind。
PS。始终测试malloc
的结果(防止失败)。 始终初始化获得的内存区域(可能使用memset(3)清除....)。
您应该编译所有警告和调试信息。如果使用GCC,请使用gcc -Wall -g
进行编译并改进代码,直到没有警告为止。
你肯定应该学会如何使用调试器(在Linux上,gdb
)并能够一步一步地执行程序并显示各种局部变量。
为了完整性(特别是在Linux上),只有一旦你成为专家C程序员,你可以考虑使用Boehm的保守garbage collector(见this link):那么你将GC_malloc
而不是malloc
,您将不需要显式free
分配的指针区域。 Boehm收藏家可能(可能稍后,特别是在更大的节目中)“神奇地”为你释放记忆。但是学习垃圾收集和reference counting(可以被视为一种糟糕的GC形式,因为它管理得不好circular references)是有用的。您也可以设计自己的GC(困难任务),就像我在qish或MELT中所做的那样......
答案 3 :(得分:1)
您在create function中在堆栈上本地创建了stu。当您从该函数返回时,会弹出堆栈,使指针指向的数据无效。