简体   繁体   中英

const char **a = {“string1”,“string2”} and pointer arithametic

main()
 {
     const char **a = {"string1","string2"};
     printf("%c", *a); /* prints s */
     printf("%s", a);  /* prints string1 */
     printf("%s", a+1);/* prints ng1 */
 }

GCC v4.8.3 prints "%s" for the last printf, where as http://codepad.org/ prints "ng1".

I thought that the code will create an array of pointers to two strings and the base address assigned to a, which allows normal pointer arithmetic. but it seems that there is something wrong with the assumption.The first printf suggests that my assumption is wrong. can anyone explain why this behavior is observed? ( note that VS 2012 has thrown an error saying too many initalizers where as GCC has thrown a warning for incompatible pointer assignment). I am aware of the warning due to incompatible pointer assignment.

const char **a is not an array of pointer to two strings. It declares a to be a pointer to pointer to const char .

const char **a = {"string1","string2"}; //No memory is allocated to store string literals 

will invoke undefined behavior and you may get either expected or unexpected results.
To declare a as an array of two pointers you need to change the declaration as

const char *a[] = {"string1","string2"};

The memory range in your program's stack looks like this: (notice that it is not allocated before assignment which is wrong)

char** a = {s, t, r, i, n ,g, 1, \0, s, t, r, i, n, g, 2, \0}

Therefore when you print the command:

printf("%c", *a);

You are dereferencing the first character of the string which is 's'.

On the other hand, when you print the command:

 printf("%s", a);

you are printing a string that starts at pointer a and finishes at '\\0'. That's why you see the output 'string1'.

Lastly, when you type "a+1" you increase the pointer in one step (example here: How to increment a pointer address and pointer's value? ). in this case because char** is a pointer, and every pointer is 4 byte, the "+1" jumps 4 chars forward. Therefore when you print the command:

printf("%s", a+1);

The printf starts at the pointer 'a' + 4 bytes and ends at '\\0'. That's why the output is 'ng1'.

Hope it was clear enough.

This is due to the following peculiar initialization performed by GCC. please see int q = {1,2}; peculiar initialization list . the statement const char **a = {"string1","string2"}; results in a being treated as if const char **a = "string1". this solves the mystery as *a would print 's', a would print string1.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM