Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C multidimensional arrays and dereferencing array pointers

I have a some confusion when it comes to multidimensional arrays. The question that came closest to helping me in my understanding was this post

Pointer address in a C multidimensional array

I have a multidimensional array initialized as follows int zippo[4][2] = {{2, 4}, {6, 8}, {1, 3}, {5, 7}};

When I print the variables zippo and *zippo it shows the same memory address for both, but when I print **zippo it prints 2 (the first value in the first subarray). My question is how does the compiler know that when zippo is dereferenced twice to print the first value of the first array? For example, for the sake of simplicity, if the memory address of zippo is 30 and the value of zippo and *zippo is 15, then you should have the following representation in memory?

memory addresses

It is my understanding that *zippo goes to memory location 15 to find the value at the location, which just so happens to be 15. So, shouldn't dereferencing it another time cause 15 to be printed yet again?

like image 462
BlaqICE Avatar asked Apr 28 '26 00:04

BlaqICE


1 Answers

You're thinking too low-level. Your question pertains to variable names and types (at the language level).

When you declare int zippo[4][2] = {{2, 4}, {6, 8}, {1, 3}, {5, 7}};, you end up with an array of four arrays of two ints. They can be accessed in many ways, depending on what you need to express. Here are some of the sub-objects involved:

| 2 | 4 | 6 | 8 | 1 | 3 | 5 | 7 |    The storage for zippo: 8 contiguous ints

|<--+---+---+---+---+---+---+-->|    zippo (the whole array), is an int[4][2]
|<--+-->|                            zippo[0] (also known as *zippo) is an int[2]
                |<--+-->|            zippo[2] is also an int[2]
|<->|                                zippo[0][0] (also known as **zippo) is an int
            |<->|                    zippo[1][1] is also an int

You can see that these sub-objects can overlap, and in some case share addresses. What still makes them distincts objects (for you, the language, and the compiler) is their type.

For example, zippo[0] and zippo[0][0] (which is its first half) have the same address, but one of them is an int, while the other is an array of two ints.

That is why you can't keep indexing into zippo[0][0], or try to use zippo[0] inside an integer calculation: even though they share the same storage, they're different objects with different meanings.

And even though indexing into arrays involves pointer arithmetic, there is no actual chain of pointers, no int*** that your first understanding implies. It's all variable names.

like image 155
Quentin Avatar answered Apr 30 '26 16:04

Quentin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!