Home > Blockchain >  Why initializing a multidimensional array of chars fails when using predefined char arrays?
Why initializing a multidimensional array of chars fails when using predefined char arrays?

Time:01-19

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:

  1. I'm inadvertently trying to modify a string literal
  2. myCharArray1 and myCharArray2 are not actually type char [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.
  3. The creation of a new char array myCharMultiArray requires some memory in an address not associated with where myCharArray1 or myCharArray2 are stored, and the syntax of char myCharMultiArray[2][10] = {myCharArray1, myCharArray2}; is actually trying to move the myCharArray1 and myCharArray2 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.

  • Related