pointer claimed with a function, not dynamically

I am wondering why the following code works. I feel like the dayname[7] is a local variable. After we return dayname[i], the pointers dayname[0] ~ dayname[6] should be disappear and also the object they pointed to. However, to my surprise, this code works and it prints out something, instead of printing nothing. Could anyone help me to explain what happens here? Thank you so much!


The second way by using dayname[7][100] does not work. It prints out wrong message. I want to understand why the first method works and the second not.
Thanks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
const char* printday(int i) // 1 prints Sunday, 2 prints Monday,...
{
    char* dayname[7]= {"Sunday", "Monday","Tuesday","Wednesday", "Thursday", "Friday", "Saturday"};
    return dayname[i];
}

int main(void)
{
    int i = 0;
    printf("Input the number 1 - 7:");
    scanf("%d", &i);
    printf("\n");
    printf( "The day is: %s", printday(i - 1));
    printf("\n");  
    return 0;
}


/**********************************************************************/
const char* printday(int i) // 1 prints Sunday, 2 prints Monday,...
{
    char dayname[7][100]= {"Sunday", "Monday","Tuesday","Wednesday", "Thursday", "Friday", "Saturday"};
    return dayname[i];
}


You are correct, dayname is a local variable.
You should avoid returning the address of a local variable.

You could also just have that function print it out instead of returning it, since that is sort of what the name of that function implies.

1
2
3
4
5
6
7
void printday(int i)
{
        if (i < 1 || i > 7)
            return;
	char dayname[7][100] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
	printf("The day is: %s\n", dayname[i - 1]);
}


I don't think the following code will compile :
char* dayname[7]= {"Sunday", "Monday","Tuesday","Wednesday", "Thursday", "Friday", "Saturday"};

It'll compile. The compiler can determine the size of the arrays at compile time. Some compilers will complain, though, about returning the address of a local variable, and fail to compile it.

You could, alternatively, change the dayname variable to static and return it

1
2
3
4
5
6
const char* printday(int i)
{
	static char* dayname[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };

	return dayname[i];
}


I would go with the first.
1
2
3
4
5
const char* printday(int i) // 1 prints Sunday, 2 prints Monday,...
{
    char* dayname[7]= {"Sunday", "Monday","Tuesday","Wednesday", "Thursday", "Friday", "Saturday"};
    return dayname[i];
}

What is the "dayname"?
It is an array of seven pointers.

What are the "Sunday", "Monday","Tuesday","Wednesday", "Thursday", "Friday", "Saturday"?
They are constant string literals. Not pointers, not variable, not in stack, nor in the heap.

What does the array initialization do?
It does store the addresses of the literal constants into the arrays.

What does the function return?
A copy of the address of one constant string literal.
That is not an address of a local variable.

Yes, the dayname is in the stack and yes, it is gone after the function returns. The names, however, are not in the dayname nor in the stack.


char dayname[7][100]= {"Sunday", "Monday","Tuesday","Wednesday", "Thursday", "Friday", "Saturday"};
That is different. The array does not contain seven pointers. It has seven character arrays.
The names are still literal constants, it is not their address that is stored in the dayname.
The content of literals, the characters are copied into the arrays.

That dayname has characters in stack. That function returns address to stack that goes poof on return.
> I don't think the following code will compile :
> char* dayname[7]= {"Sunday", "Monday","Tuesday","Wednesday", "Thursday", "Friday", "Saturday"};
>> It'll compile. The compiler can determine the size of the arrays at compile
>> time. Some compilers will complain, though, about returning the address of a
>> local variable, and fail to compile it.
ISO C++ forbids converting a string constant to ‘char*’



> However, to my surprise, this code works and it prints out something, instead
> of printing nothing
¿why is it so hard to understand the meaning of undefined?
Last edited on
Most compilers will still not reject implicit conversions of string literals to 'char *', at least not by default.
Thanks for all help! keskiverto, thank you so much! I learned a lot from your answer! I did not realize that constant string literals has static duration. Although dayname[m][n] behaves like a pointer to pointer and you can do all pointer type operation on it, but it is just a container to store the copy of several strings. There is no pointer pointing to the address of any of those string literals. Thanks

Many thanks again!
Topic archived. No new replies allowed.