Question

I'm trying to allocate a 2D char array to be accessed like ary[i][j], using this code:

#define stringmaxlen 20

void do_alloc( char ***vals, int valscount ){
    *vals = (char**) calloc( sizeof( char** ), valscount );
    int i = 0;
    for ( ; i<valscount; i++ )
        *vals[i] = (char*) calloc( sizeof( char* ), stringmaxlen );
}

int main( ){
    //......
    char** ary;
    do_alloc( &ary, 10 );
    strcpy( ary[0], "test" );
    //......
}

Unfortunately, this causes an overflow somewhere and the program have a bug in execution, I got some references from here for the dynamic allocation: http://staff.science.nus.edu.sg/~phywjs/CZ1102/lecture20/sld014.htm.

I like to know what's wrong here and how to solve the issue, thanks.

Was it helpful?

Solution

You got the operator precedence wrong: *vals[i] evaluates as *(vals[i]), not as (*vals)[i]. See http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Operator_precedence for details.

The fix is to change *vals[i] to (*vals)[i].

Also, the allocation *vals[i] = (char*) calloc( sizeof( char* ), stringmaxlen ); is wrong. It allocates way too much memory because it allocates space for stringmaxlen pointers, but you need only stringmaxlen characters.

OTHER TIPS

I want to add the following to cmaster's answer.

Instead of

*vals = (char**) calloc( sizeof( char** ), valscount );

use

*vals = (char**) calloc( sizeof( char* ), valscount );

Instead of

    (*vals)[i] = (char*) calloc( sizeof(char*), stringmaxlen );

use

    (*vals)[i] = (char*) calloc( sizeof(char), stringmaxlen );

In the first case, the size of memory allocated doesn't change since sizeof(char**) is the same as sizeof(char*). However that's not true with the second case. sizeof(char) is 1 while sizeof(char*) is larger -- 4 for 32 bit hardware, 8 for 64 bit hardware.

More importantly, it clarifies the intention -- that you would like to allocate memory for stringmaxlen characters, not stringmaxlen pointers to characters.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top