Reputation: 129
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.
Upvotes: 3
Views: 105
Reputation: 206667
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.
Upvotes: 3
Reputation: 40645
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.
Upvotes: 7