I am new to C and was trying to play around with different ways to initialize arrays of chars according to various ways explained here and found one difference I cannot explain based on what I could learn from that previous thread or other resources I've been learning from. Stopping at a breakpoint just below the lines shown below in gdb:
char myCharArray1[] = "foo";
char myCharArray2[] = "bar";
char myCharMultiArray[2][10] = {myCharArray1, myCharArray2};
char myCharMultiArrayLiteral[2][10] = {"foo", "bar"};
In gdb I notice the following:
ptype myCharMultiArray
type = char [2][10]
ptype myCharMultiArrayLiteral
type = char [2][10]
ptype myCharMultiArray[0]
type = char [10]
ptype myCharMultiArrayLiteral[0]
type = char [10]
info locals
myCharArray1 = "foo"
myCharArray2 = "bar"
myCharMultiArray = {"\364\360\000", "\000\000\000"}
myCharMultiArrayLiteral = {"foo", "bar"}
Why do the contents of myCharMultiArray
and myCharMultiArrayLiteral
differ? Where do the numbers in myCharMultiArray
\364\360
even come from?
If I were to try to explain why this is happening from what I've read so far, is it may have something to do with the following ideas:
- I'm inadvertently trying to modify a string literal
myCharArray1
andmyCharArray2
are not actually typechar [4]
(despite what gdb tells me) and they are just pointers to the first character in the string literals (i.e. the address of where the 'f' and 'b' are stored respectively.- The creation of a new char array
myCharMultiArray
requires some memory in an address not associated with wheremyCharArray1
ormyCharArray2
are stored, and the syntax ofchar myCharMultiArray[2][10] = {myCharArray1, myCharArray2};
is actually trying to move themyCharArray1
andmyCharArray2
data as opposed to copying it. Which is not possible for some reason I don't yet quite grasp.
Adding a link to a relevant topics (but still can't find a duplicate).
CodePudding user response:
First of all please use this: What compiler options are recommended for beginners learning C?
After which a compiler like gcc will tell you that the code is invalid C.
error: initialization of 'char' from 'char *' makes integer from pointer without a cast [-Wint-conversion]
You are debugging invalid C so there's not much point in trying to making sense of whatever the compiler let through in "lax mode" just because you compiled with non-standard compiler settings.
Specifically, your problem boils down to the fact that C does not allow us to copy arrays during initialization/assignment. Why it was designed like that is a long story and there's not much in the way of a rationale, just accept that C doesn't allow it. Your first arrays are of type char[4]
indeed but decay into a char*
when used in most expressions (hence "from char*
" in the compiler error).
A char
array initializer list expects char
items as initializers, hence "error: initialization of 'char'". Even if it is a 2D array, it still wants char
initializers, but allows for nested braces which is good practice. So you'd do
{ {'f', 'o', 'o', '\0'}, {'b','a','r','\0} }
and that's correct C, although a pain to write out like that. Therefore string literals are allowed as an alternative form of initialization.
In case of string literals, yes they are by themselves to be regarded as arrays, but the array initialization rules in C mention string literals as a special case with special initialization rules.
char myCharMultiArrayLiteral[2][10] = {"foo", "bar"};
is therefore fine.