3

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.

2
  • The parameters you use for calloc are in reversed order as you can see from here and there; although I don't really know whether it would cause an erroneous behaviour. Commented Mar 24, 2014 at 21:16
  • 1
    @ThoAppelsin The order of parameters to calloc is irrelevant on any platform that I know of. Commented Mar 24, 2014 at 21:17

2 Answers 2

7

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.

Sign up to request clarification or add additional context in comments.

1 Comment

yeah! that's it, now the issue is fixed, the precision is important! thank you man!
3

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.

1 Comment

You could have avoided these errors by using the idiom: P = calloc(N, sizeof *P);, e.g. *vals = calloc( valscount, sizeof **vals ); etc.

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.