Today, I asked me, how char ** objects are saved in memory or in binary files. I tested that with the following code snippet:
char **array = (char *)malloc(3 * sizeof(char *));
array[0] = "Foo"; // Length: 3
array[1] = "Long string"; // Length: 11
array[2] = "Bar"; // Length: 3 => Full length: 17
int length = 17;
I write this array to a file:
FILE *file = fopen(...);
fwrite(array, length, 1, file);
fclose(file);
The great thing is that when I read again this array from file with the following code, the string lengths are read successfully without saving more than 17 bytes.
FILE *file = fopen(...);
int length = 17;
char **array = (char *)malloc(length);
int index = 0;
int parsedLength = 0;
while (parsedLength < length)
{
char *string = array[index];
int stringLength = strlen(string);
printf("%i: \"%s\" (%i)\n", index, string, stringLength);
parsedLength += stringLength;
++index;
}
I get an output that equals:
0: "Foo" (3)
1: "Long string" (11)
2: "Bar" (3)
How does the compiler know, how long each string in the array is?
Pointers are saved to a file like numbers (or better addresses) so the fact that your code works is an illusion created by the fact that you are probably saving and loading them inside the same program in the same run (so since these string are literals, their address is mostly fixed in data segment).
What you are doing is completely wrong because array's layout in memory is the following (I'm assuming 4 bytes pointers):
XXXXXXXX YYYYYYYY ZZZZZZZZ ( = 12 bytes)
^ ^ ^
| | pointer to "Bar"
| pointer to "Long String"
pointer to "Foo"
but you are saving 17 bytes onto the file, 12 of which are just memory addresses.
To correctly save strings in the file you will certainly need to store the whole data contained and its length. Something like:
for (int i = 0; i < ARRAY_LENGTH; ++i) {
char *string = array[i];
unsigned int length = strlen(string);
fwrite(&length, sizeof(unsigned int), 1, out);
fwrite(string, sizeof(char), length, out);
}
for (int i = 0; i < ARRAY_LENGTH; ++i {
unsigned int length;
fread(&length, sizeof(unsigned int), 1, in);
array[i] = calloc(sizeof(char), length);
fread(array[i], sizeof(char), length, in);
}
In don't think your program works.
Try to write a new program which read your file, or try to open the binary file with an hex editor. The strings aren't present in it.
char ** array is an array of pointer not an array of char and its size is 3*4 = 12 on 32 bits common environment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With