Reputation: 834
I have managed to produced a code that works perfectly fine and does exactly what it should. My problem is: I absolutely don't understand why. In my understanding it should NOT work.
#define PARAMS 12
char** parseFile(char* tmp[], char* location) {
// Parse a file at <location> and retrieve 6 key: value pairs from it.
// All key: value pairs are stored in tmp, resulting in an array of
// 12 char pointers, each pointing to a char array that contains either
// a key or a value.
// ...
do {
yaml_parser_scan(&parser, &token);
if (token.type == YAML_SCALAR_TOKEN && i<PARAMS) {
strcpy(tmp[i], (char*)token.data.scalar.value);
i++;
}
if (token.type != YAML_STREAM_END_TOKEN) {
yaml_token_delete(&token);
}
} while (token.type != YAML_STREAM_END_TOKEN);
// ...
return tmp;
}
int main(int argc, char* argv[]) {
int i=0;
char **tmp = (char **)calloc(PARAMS, sizeof(char *));
char **params = (char **)calloc(PARAMS, sizeof(char *));
for (i=0; i<PARAMS; i++) {
tmp[i] = (char *)calloc(32, sizeof(char));
params[i] = (char *)calloc(32, sizeof(char));
}
memcpy(params, parseFile(tmp, argv[1]), sizeof(char) * 56); // WHY 56?
for (i=0; i<PARAMS; i++) {
printf("PARAM_[%d] = %s\n", i, params[i]);
}
free(tmp);
free(params);
return 0;
}
I could swear that I would have to specify a size of sizeof(char) * 384
(1 * 12 * 32) in memcpy for the code to work. But if I do, it doesn't. It only works and produces the correct result if I specify sizeof(char) * 56
. Why 56? What's that value supposed to mean? I do realise that I have 6 key: value pairs and that 6 * 8 + 8 is 56, but I still don't get it.
[EDIT]
The use case is this:
The program connects to a server based on connection parameters (IP address, port) that are provided in a yaml configuration file. A minimalistic version of that file could look like this:
---
# Connection parameters
tx_addr: 192.168.1.124
tx_port: 8080
The program needs the values of the key:value pairs as those are passed to functions which establish the connection to the server. So, what I need to do is to parse the configuration file and look for allowed keys (the parameters could be anything; I only know the keys). E.g., if the key "tx_addr" is found, the program knows that the value to that key shall be passed as the IP address parameter of the functions establishing the server connection.
Upvotes: 0
Views: 170
Reputation: 44274
I assume that your aim is to copy all key:value pairs from tmp
to params
.
You can't copy all the key:value pairs from tmp
to params
with a single memcpy
. You can't be sure that malloc
have given you two consecutive memory areas.
You have to copy the strings one-by-one.
parseFile(tmp, argv[1]);
for (i=0; i<PARAMS; i++) {
memcpy(params[i], tmp[i], 32);
}
In order to get two consecutive memory areas (so that you can copy with a single memcpy
), you need to allocate the variables as 2D arrays (https://stackoverflow.com/a/40847465/4386427 and https://stackoverflow.com/a/42094467/4386427).
Upvotes: 1