2

I have the following code in C

#include <stdio.h>
 
char *gstr[] = { "Hello", "World" };
 
void func(char str[][8]) {
    printf("%p\n", (void *)str);
    printf("%p\n", (void *)(str + 1));
    printf("%s\n", *(str + 1));
}
 
int main(void) {
    printf("%p\n", (void *)gstr);
    printf("%p\n", (void *)(gstr + 1));
    printf("%s\n", *(gstr + 1));
 
    printf("Calling Function\n");
 
    func(gstr);
    return 0;
}

The following is the output

0x556f11ddd010
0x556f11ddd018
World
Calling Function
0x556f11ddd010
0x556f11ddd018
$��oU

I cannot understand why printf("%s\n", *(str+1)); in the function func does not print the string world.

3
  • What made you choose the prototype void func(char str[][8])? How did you compile your code - did you receive any warnings? Commented Jan 9, 2021 at 14:46
  • 1
    If using gcc for example, compile with gcc -Wall -Werror -Wextra -g and resolve any errors that show. You can't expect a certain behavior when you run invalid code Commented Jan 9, 2021 at 14:48
  • If you compile if with the command I suggested, you will see the error immediately: incompatible pointer type ... expected ‘char (*)[8]’ but argument is of type ‘char **’ Commented Jan 9, 2021 at 14:49

2 Answers 2

3

char *gstr[] = {"Hello", "World"}; declares gstr to be an array of pointers to char.

By itself, char str[][8] declares str to be an array of arrays of eight char. However, as a function parameter, it is automatically adjusted from an array to a pointer: It declares str to be a pointer to an array of eight char.

A pointer to an array is different from an array of pointers.

Your compiler should have warned you that the type of gstr in func(gstr) is incompatible with the type of the parameter in void func(char str[][8]). Pay attention to the messages from your compiler.

To pass gstr to func correctly, change the declaration of func to func(char *str[]) or the equivalent func(char **str).

func(gstr) passes the address of the first element of gstr to the function. Since gstr is an array of pointers, the address of its first element is the address of a pointer (that being a pointer to the first character of "Hello").

In func, the function expects a pointer to an array of eight char. If it uses the address it is given for that, it is pointing to a pointer instead of an array of eight char. Passing that to printf attempts to print the bytes representing the pointer as if they were a string of characters.

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

Comments

1

You can compile the code below to see the output.

#include <stdio.h>
 
char *gstr[] = {"Hello", "World"};
 
void func(char str[][8]) {
    printf("%p\n", (void*) str);
    printf("%p\n", (void*) *str);
    printf("%p\n", (void*) (str+1));
    printf("%p\n", (void*) *(str+1));
    printf("%s\n", *(str+1));
}
 
int main(void) {
    printf("%p\n", (void *) gstr);
    printf("%p\n", (void *) *gstr);
    printf("%p\n", (void*) (gstr+1));
    printf("%p\n", (void*) *(gstr+1));
    printf("%s\n", *(gstr+1));
 
    printf("Calling Function\n");
 
    func(gstr);
    return 0;
}
0x100402010
0x100403000
0x100402018
0x100403006
World
Calling Function
0x100402010
0x100402010
0x100402018
0x100402018
0@

The compiler know that gstr is an array of pointers, so that in function main, the object at gstr + 1 will be interpreted as char* and you get the expected result.

However in function func, the bytes at str + 1 will be interpreted as char [8], and you know it will return the first address of this object which is str+1

Comments

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.