ci7i2en4
ci7i2en4

Reputation: 834

How does this array size come about?

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

Answers (1)

4386427
4386427

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

Related Questions