this program returns a pointer to a structure.
When i print the contents, the name is not being displayed properly, where as the other tw
As Joachim Pileborg answered you should not return a pointer to a local variable. BTW if you compile with a recent GCC using gcc -Wall -g
(e.g. enabling almost all warnings and debug info) you should get a warning.
So in practice, you should decide that your create
returns a heap pointer, and adopt then obey the convention that its caller is freeing that pointer.
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;
}
Read carefully the wikipages on C dynamic memory allocation, manual memory management, heap, memory leaks and malloc(3) man page. If you have the luck of coding on Linux, learn about valgrind.
PS. Always test the result of malloc
(against failure). Always initialize the obtained memory zone (maybe clearing it with memset(3)....).
You should compile with all warnings and debug info. If using GCC, compile with gcc -Wall -g
and improve your code till you got no warnings.
You definitely should learn how to use the debugger (on Linux, gdb
) and be able to step by step the program and display various local variables.
For completeness (notably on Linux), and only once you become an expert C programmer, you might consider using Boehm's conservative garbage collector (see this link): then you would GC_malloc
instead of malloc
and you won't need to explicitly free
the allocated pointer zone. The Boehm collector might (perhaps later, notably in bigger programs) "magically" free the memory for you. But learning about garbage collection and reference counting (which can be viewed as a poor form of GC, since it does not manage well circular references) is useful. You could also design your own GC (difficult task), like I did in qish or MELT ...
The problem here is that you're returning a pointer to a local variable. Local variables goes out of scope once the function they are defined in returns. That means that the pointer you return will point to unallocated memory after the function returns. Using that pointer will lead to undefined behavior.
There are three ways to solve this:
static
local variable. It also will have the lifetime equal to the program.Points 1 and 2 have a problem in that then you can only have a single object. If you modify that object, all places where you have a pointer to that single object will see those changes.
Point 3 is the way I recommend you go. The problem with that is that once you're done with the object, you have to free the memory you allocate.
You created stu locally on the stack in your create function. When you returned from that function, the stack was popped, invalidating the data you pointer points to.
You create a local variable stu
which lives in a function create()
. A pointer on this variable is incorrect outside function create()
.