c

Problem with obtaining a pointer from a function via an 'out' parameter


I wrote a program to test retrieving a pointer (to a struct) from a function via double-pointer 'out' parameter:

#include <stdio.h>
#include <stdint.h>

struct mastructrure_t
{
  int a;
  int b;
};

int Test(struct mastructrure_t **var5)
{
  struct mastructrure_t *var3;
  struct mastructrure_t test;
  test.a = -1313;
  test.b = -1414;
  var3 = &test;
  printf("addr pointer var1=   %p\n", var5);
  printf("\n");
  printf("addr test=           %p\n", &test);
  printf("addr3 similaire test=%p\n", var3);
  *var5 = var3;
  printf("var addr test=       %p\n", *var5);
  
  printf("addr a=%p\n", &(var3->a));
  printf("addr b=%p\n", &(var3->b));
  return 0;
};

int main(int argc, char **argv)
{
  struct mastructrure_t *var1;
  
  printf("addr pointer var1=   %p\n", &var1);
  Test(&var1);
  printf("addr a=%p\n", &(var1->a));
  printf("addr b=%p\n", &(var1->b));
  //printf("%s", "\n");
  printf("a=%d\n", var1->a);
  printf("b=%d\n", var1->b);
  return 0;
}

That code works. The printf calls show var1->a = -1313 and var1->b = -1414. But if I uncomment the commented-out printf call, the output shows different values for var1->a and var1->b! I don't understand why. Does my code have a memory leak? Am I'm not using printf in the right way?

I was hoping in each case to see:
var1->a = -1313
var1->b = -1414


Solution

  • That code works. The printf calls show var1->a = -1313 and var1->b = -1414.

    That's plausible, but in no way guaranteed.

    But if I uncomment the commented-out printf call, the output shows different values for var1->a and var1->b!

    That's also plausible.

    Does my code have a memory leak? Am I'm not using printf in the right way?

    No and no. The issue is that using parameter var5, your Test() function is setting main()'s var1 to point to a local variable of Test(). There's no problem with that while Test() is executing, but that local (structure) variable's lifetime ends as soon as execution of Test() completes. After Test() returns, it is no longer defined what var1 points, so dereferencing that pointer produces undefined behavior.

    UB does not necessarily mean that your program will crash, or even that it will behave differently than you (without justification) expect. But it might do. And it might behave differently on different runs, or produce unexpected behavior only for some inputs. One of the classic telltales of UB is that small program changes produce unrelated changes in behavior.

    You have several alternatives for fixing your program, among them: