简体   繁体   中英

returning pointer to a structure in C

this program returns a pointer to a structure .
When i print the contents, the name is not being displayed properly, where as the other two variables are being properly printed.
What could be the problem? Here is the code in 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;
}

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:

  1. Use a global variable, and return a pointer to that. The lifetime of a global variable is the lifetime of the program.
  2. Use a static local variable. It also will have the lifetime equal to the program.
  3. Allocate the structure dynamically when needed, and return that pointer.

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 create a local variable stu which lives in a function create() . A pointer on this variable is incorrect outside function create() .

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 (eg 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) ....).

addenda: good habits

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.

addenda: using Boehm GC

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 ...

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM