1

I've a strange behavior while i'm trying to set a NULL value at the end of array of string (array of char) in c. I need to pass parameters to a process with execv, and i've all parameters with int type, so i'm trying to get an array of strings with all parameters casted in char array. I made a function that returns this array of strings, but when I set the last value of array to NULL (to have a terminating value in parameters) I lost the value stored in second position. If I remove the NULL value, no issue happens. This is the code, hope someone can help me

char **getParams(int offset, short isNode, int first) {

    printf("Get params\n");

    int args = 8;
    int totalSize = 0;
    int tmp[args];

    tmp[0] = sizeof(char) * 5; // user / node
    tmp[1] = snprintf(NULL, 0, "%d", x);
    tmp[2] = snprintf(NULL, 0, "%d", x2);
    tmp[3] = snprintf(NULL, 0, "%d", x3);
    tmp[4] = snprintf(NULL, 0, "%d", x4);
    tmp[5] = snprintf(NULL, 0, "%d", x5);
    tmp[6] = snprintf(NULL, 0, "%d", x6);
    tmp[7] = snprintf(NULL, 0, "%d", x7);

    int i = 0;
    for (i = 0; i < args; i++) totalSize += tmp[i];

    char **_pars = malloc(totalSize + sizeof(NULL));
    
    i = 0;
    for (i = 0; i < args; i++) _pars[i] = malloc(tmp[i]);
    
    _pars[0] = isNode == 1 ? "aaaa" : "bbbb" ;
    sprintf(_pars[1], "%d", x);
    sprintf(_pars[2], "%d", x2);
    sprintf(_pars[3], "%d", x3);
    sprintf(_pars[4], "%d", x4);
    sprintf(_pars[5], "%d", x5);
    sprintf(_pars[6], "%d", x6);
    sprintf(_pars[7], "%d", x7);
    printf("Value: %s", _pars[1]); /// Print without problem value
    _pars[8] = NULL;   //// ,--- Here happens the issue
    printf("Value: %s", _pars[1]); /// Doesnt print any value

    return _pars;
}

I also tried to put this after the for in which i malloc array position, but without result

_pars[8] = malloc(sizeof(NULL));
0

2 Answers 2

3

All your allocations are wrong.

First of all you want to create an array of 8 elements, so the first allocation should be

char **_pars = malloc(8 * sizeof *_pars);

Or if you want the array to be terminated by a null-pointer you need to allocate 9 elements (exchange the 8 for a 9 above).

Secondly the size returned by snprintf does not include the null-terminator, so all your calls

_pars[i] = malloc(tmp[i]);

should be

_pars[i] = malloc(tmp[i] + 1);

to fit the null-terminator.


On another note, all your code could be simplified quite a lot if you put all the x values in an array:

int exes[8] = { x, x2, x3, x4, x5, x6, x7 };

Because then you could use loops for all repetitive code:

for (unsigned i = 1; i < 8; ++i)
{
    tmp[i] = snprintf(NULL, 0, "%d", exes[i]);
}
Sign up to request clarification or add additional context in comments.

3 Comments

Hi, many thanks for your answer, is really helpful. But I don't understand what you mean when you say char **_pars = malloc(8 * sizeof *_pars);, if i change the totalSize by assigning it correctly (by using + 1 to fit null terminator) is not the same thing? I don't understand how i can use sizeof (*_pars) if i've not defined a size for a single parameter
@EmmeDeveloper The size in totalSize is the size of the strings themselves (without the eight null-terminators), not the number of elements for the array _pars. Think of _pars as an array of pointers (equivalent to char *_pars[8];) and it would make more sense.
Oh ok got it thanks, i tried to allocate totalSize to use less memory, but i forget that each element of array must have the same size, so i cannot use totalSize but i need size of one element * number of element in the array. Many thanks
0

_pars is assumed to be an array of pointers to char, which implies

_pars = malloc(args * sizeof(char*));

But you allocate the memory for the strings, the pointers should point to.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.