C,C++ structs doubt

Hi, I have a small doubt in C/C++ with respect to structs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
struct A
{
  char *name; 
};

struct B
{
  char name[5];
};

void write_ptr(char *name)
{
  A *a = (A *) malloc(sizeof(A));
  a->name = name;
  fwrite(a, sizeof(A), 1, f); // f is file pointer
}

void write_cpy(char *name)
{
  B *b = (B *) malloc(sizoof(B));
  strcpy(b->name, name);
  fwrite(b, sizeof(B), 1, f); // f is file pointer
}


I ran this code and opened the output file, with write_cpy I could see the name written, but not with write_ptr the strange thing is when reading back the file into struct both works fine, how is this happening? will file produced by write_ptr be readable if distributed?
Structure A contains only pointer to string. When calling fwrite, it will write into file 4 or 8 bytes of pointer (depending on whether you are running 32-bit or 64-bit code). Not the actual string contents, but only address of string.

If you are reading this file back into same program after you wrote it to file, the pointer is still valid, so that's why you thing "reading back works fine". If you would actually close the program, comment out writing part and then restart it, you would see that reading back string this way would produce garbage. Pointer value would be read back correctly of course, but where it points to is something undefined. It may or may not be valid memory block.

Or you can do this experiment - call fwrite, replace name with something else (a->name[0] = 'X'), then read it back and check what it the string. It will be modified string (with 'X' in it), not the original string what you think it "wrote" to file. Because you are reading back only pointer, not the actual string contents.

If you want to write contents of structure A to file, you will need to call fwrite on individual string itself - fwrite(a->name, strlen(a->name), 1, f). And then read it back. Make sure you handle length of string correctly (either store it explicitly in file, or store \0 terminator).

Structure B contains actual 5 characters of string. So when writing it to file, the actual 5 bytes of string is written to file. That's why reading it back will always work.

Edited by Mārtiņš Možeiko on
Thank you for the quick reply, I was also thinking the same thing but was not sure of it, Thanks for the clarification.