0

I have a structure that has name and surname. I want to write two pointers to array (infoArr). Here's the code:

#include <stdio.h>
#include <stdlib.h>

typedef struct{
    char* surname;
    char* name;
}Info;

int main(int argc, const char * argv[]) {

    Info **infoArr = calloc(2, sizeof(Info*));  

    char* name1 = "Ian";
    char* surname1 = "Jones";
    char* name2 = "Ann";
    char* surname2 = "Stephens";

    Info *info = malloc(sizeof(Info));
    info->surname=surname1;
    info->name=name1;
    infoArr[0]=info;
    printf("infoArr[0]: %s %s\n",infoArr[0]->surname,infoArr[0]->name);

    info->surname=surname2;
    info->name=name2;
    infoArr[1]=info;
    printf("infoArr[1]: %s %s\n\n",infoArr[1]->surname,infoArr[1]->name);
    free(info);

    printf("infoArr[0]: %s %s\n",infoArr[0]->surname,infoArr[0]->name);
    printf("infoArr[1]: %s %s\n",infoArr[1]->surname,infoArr[1]->name);

    free(infoArr);

    return 0;
}

And as a result I receive this:

infoArr[0]: Jones Ian
infoArr[1]: Stephens Ann

infoArr[0]: Stephens Ann
infoArr[1]: Stephens Ann

What is wrong here? Why it changes first element then?

Yakimget
  • 25
  • 4

2 Answers2

1

Do the following

infoArr[0] = malloc ( sizeof(Info) );
infoArr[1] = malloc ( sizeof(Info) );

This will create two different structs. Now assign to each struct as

infoArr[0]->surname = "...";

Finally don't forget to free.

Ajay Brahmakshatriya
  • 8,993
  • 3
  • 26
  • 49
0

In your code, infoArr[n] are pointers, they point to some memory.

Next, you make infoArr[n]s point to the value held by info, via the assignments,

 infoArr[0]=info;
 ...
 ....
 ...
 infoArr[1]=info;

So, after you call free(info);, any access made to infoArr[0] or infoArr[1] will be invalid, as the memory location they point to has already been passed to free(), they don't necessarily point to any valid memory anymore. This causes causes undefined behavior.

Quoting from C11, chapter §7.22.3,

[...] The lifetime of an allocated object extends from the allocation until the deallocation. [...]

So, after the deallocation, the pointer to the object becomes invalid, any access would be UB, as mentioned in chapter §6.2.4

[...] If an object is referred to outside of its lifetime, the behavior is undefined. The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261