Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C - 'char **' differs in levels of indirection from 'char (*)[6]'

Tags:

c

Can someone please explain to me what's wrong with the following, and more importantly why?

int main( int argc, char *argv[] )
{
    char array[] = "array";
    char **test;
    test = &array;

    *test[0] = 'Z';

    printf( "%s\n", array );

    return 0;
}

EDIT

My example above was based on a function like this that was crashing:

void apple( char **pp )
{
    *pp = malloc( 123 );
    *pp[0] = 'a'; // technically this is correct but in bad form
    *pp[1] = 'b'; // incorrect but no crash
    *pp[2] = '\0'; // incorrect and crash
}

As pointed out to me by Vaughn Cato although *pp[0] = 'a'; does not crash it is in bad form. The correct form is the parenthesis

void apple( char **pp )
{
    *pp = malloc( 123 );
    (*pp)[0] = 'a'; // correct
    (*pp)[1] = 'b'; // correct
    (*pp)[2] = '\0'; // correct
}

Also as another poster MK pointed out the FAQ covers the difference between arrays and pointers: http://www.lysator.liu.se/c/c-faq/c-2.html

like image 562
loop Avatar asked Sep 23 '11 03:09

loop


2 Answers

This would be the way to do what you seem to be trying to do:

int main( int argc, char *argv[] )
{
  char array[] = "array";
  char (*test)[6];
  test = &array;

  (*test)[0] = 'Z';

  printf( "%s\n", array );

  return 0;
}

test is a pointer to an array, and an array is different from a pointer, even though C makes it easy to use one like the other in my cases.

If you wanted to avoid having to specify a specific sized array, you could use a different approach:

int main( int argc, char *argv[] )
{
  char array[] = "array";
  char *test;
  test = array;  // same as test = &array[0];

  test[0] = 'Z';

  printf( "%s\n", array );

  return 0;
}
like image 86
Vaughn Cato Avatar answered Sep 17 '22 14:09

Vaughn Cato


test = &array

is wrong because test is of type char** and &array is a char(*)[6] and is a different type from char**

An array isn't the same type as char* although C will implicitly convert between an array type and a char* in some contexts, but this isn't one of them. Basically the expectation that char* is the same as the type of an array (e.g: char[6]) is wrong and therefore the expectation that taking the address of an array will result in a char** is also wrong.

like image 41
sashang Avatar answered Sep 17 '22 14:09

sashang