Lion King
Lion King

Reputation: 33813

What is the difference between "char *var[3]" and "char var[3][15]"?

I am confused between the following two ways:

char var[3][15] = {"Hello_world!", "good", "bad"}; // as known this is for an 2D array.  
char *var[3] = {"Hello_world!", "good", "bad"}; // and this I think also 2D array, but how.
  1. What's the difference between them?
  2. What are the cases to use that or that?

Upvotes: 1

Views: 338

Answers (4)

JoshG79
JoshG79

Reputation: 1687

The first is actually creating a block of 45 (3*15) bytes in memory, with a base at some memory location that will be called var. C will let you address these as a two-dimensional array so that var[a][b] is the same as *(var + a*15 + b). The compiler will then pre-fill those 45 bytes with your strings in the right locations to maintain the 2D-array feel.

The second method is allocating one block of memory with 3 pointers. If your pointers are 8 bytes each, then var is a 1D array of 24 (3*8) bytes. In addition, C will create some other arrays somewhere else in memory with your data strings. It will then point the former to the latter. That is, the following is roughly equivalent to your second method:

char s1[] = "Hello_world!";
char s2[] = "good";
char s3[] = "bad";
char *var[3] = { &(s1[0]), &(s2[0]), &(s3[0]) };

Note however that the equivalence from the first method of var[a][b] == *(var + a*15 + b) is not maintained. For example, var[0] will point to s1, which could technically be anywhere in memory (and has no relationship to where s2 or s3 are). Then var[0][b] is some offset from that location.

Upvotes: 1

Mooing Duck
Mooing Duck

Reputation: 66922

There's two types of two dimensional arrays, and you have both types there.

With the first one, it's an array of 5 char[15] objects, which are layed out sequentially in memory. Unused bytes in the end of each "row" are (in your particular case but not always) filled with zeros. This is what most people think of when you say a "two dimensional array", but some people call it a "square" array to distinguish it from the other type. When you initialize it, the string literals are copied into the array directly.

[0][ 0] = 'H'
[0][ 1] = 'e'
...
[0][14] = '\0' (end of each row is filled with zeros)
[1][ 0] = 'G'
[1][ 1] = 'o'
...
[3][13] = '\0' (end of each row is filled with zeros)
[3][14] = '\0' (end of each row is filled with zeros)

The second one is an array of 5 char* (pointers) which usually refers to an array of char objects that do not have to be the same size. If they do point at arrays of char objects, this can be accessed as a two dimensional array. Since the length of each array may be a different size, this is referred to as a "jagged array". In your code, there's three "rows", the first is 13 chars long, the second is 5 chars long, and the third is 4 chars long. The first index of the array is sequential in memory, but arrays forming the "inner" index can be anywhere in memory. When you initialize it, this forms a one-dimensional array that points at the actual string literals. Together, they form a two-dimensional array.

[0] -> "Hello_world!"
[1] --------------------------------->"good"
[2] ---------------------->"bad"

Upvotes: 1

Jiminion
Jiminion

Reputation: 5168

The first is a 2D array of chars. The second is a 1D array of char * (pointers).

Upvotes: 0

Peter Alexander
Peter Alexander

Reputation: 54270

The first is a two-dimensional array.

The second is a one-dimensional array of pointers. If those pointers point to arrays then it will also be a two-dimensional array, but that isn't guaranteed simply by looking at the types.

For example, you could have an array of 5 NULL pointers:

char *var[5] = {0, 0, 0, 0, 0};

In this case it certainly is not a two-dimensional array, and trying to access var[i][j] will result in undefined behaviour (most likely a memory access error, or "segfault").

Upvotes: 1

Related Questions