-1

I'm quite new in C language, so this "problem" is very confusing for me.

I wanted to create 2D array using array of int pointers (rows) which points to arrays of ints (columns) in one block of memory. I did it and it works but I'm not sure why after I checked something.

I've used malloc to allocate 48 bytes (2x4 array) in the heap (I'm on x86-64 machine):

int **a;
a = (int **)malloc(sizeof(int*) * 2 + sizeof(int) * 2 * 4);

Now lets assume that this is the whole 48 bytes in memory. I wanted 2 row's array so I needed 2 pointers to arrays of ints - a[0], a[1]:

 ----------------------------------------------------------------
 | a[0] | a[1] |                                                |
 ----------------------------------------------------------------
               ^
               |

I assumed that all pointers are 8 bytes long and that address of a[2] (arrow) is the place where I can start storing my values (arrays of ints). So I did...

int *addr = (int*)&a[2];
a[0] = addr;
addr += 4;
a[1] = addr;

This is working perfectly fine, I can easily fill and print 2D array. Problem is that when I was writing int *addr = (int*)&a[2]; I was sure that this will be the address of a[0] plus 2 * 8 bytes, but it wasn't. I've checked it at another example with this simple code:

int *p;
int **k;

p = (int*) malloc(30);
k = (int**) malloc(30);

printf("&p = %p %p %p\n", &p[0], &p[1], &p[2]);
printf("&k = %p %p %p\n", &k[0], &k[1], &k[2]);

Output:

&p = 0x14d8010 0x14d8014 0x14d8018 <-- ok (int = 4 bytes)
&k = 0x14d8040 0x14d8048 0x14d8050 <-- something wrong in my opinion (ptrs = 8 bytes)

My question is: Why the third address of the pointer in array is 0x14d8050 not 0x14d8056. I think it might be because 0x14d8056 is not the best address for ints but why is that and why it happens only when dealing with array of pointers?? I've checked this on x86 machine and pointer has "normal" values

&p = 0x8322008 0x832200c 0x8322010
&k = 0x8322030 0x8322034 0x8322038

I know this might be an obvious or even stupid question for someone so please at least share some links with information about this behavior. Thank you.

python
  • 198
  • 1
  • 5
  • 13

2 Answers2

0

Numbers prefixed by 0x are represented in hexa decimal.

Thus, 0x14d8048 + 8 == 0x14d8050 is expected.

timrau
  • 22,578
  • 4
  • 51
  • 64
0

as timrau said in his comment 0x14d8048 + 8 is not 0x14d8056 but 0x14d8050 because it's hexadecimal concerning your 2D array , I'm not sure why it worked but that's not the way to create one. there are two ways for creating a 2D array , the first and simple one is " statically " and it goes like this : int a[2][4]; .

the second one , the one you tried , is dynamically , the slightly more complicated and it goes like this

int **a;
int i;
a = malloc(2 * sizeof(*int));
for(i = 0 ; i < 2 ; i++)
     a[i] = malloc(4 * sizeof(int));
Farouq Jouti
  • 1,657
  • 9
  • 15
  • I started learning C just a few days ago but even now I can't agree to what you are saying. I've created mine in one block of memory so it's only a one call to malloc. Now try your code with 2000 rows, which ends in 2000+1 calls to malloc. – python Aug 26 '14 at 01:42
  • It doesn't matter whether you create all of the storage at one time thinking of the array as a 1-dimensional array, or create your storage row-by-row thinking of it as a 2-dimensional array -- all data will we laid out sequentially in memory. In reality there are no 2-dimensional arrays in C, it is just a convenient notation for handling offset values to create 2-dimensional array behavior. – David C. Rankin Aug 26 '14 at 02:43
  • I know how every array is stored in memory @DavidC.Rankin. I just can't agree that for example 1001 calls to malloc is faster than just one call. – python Aug 26 '14 at 12:04
  • Your point is well-taken, but to be fair, there wasn't a speed consideration discussed. 1 call is definitely faster that 1001 calls, but from a performance standpoint, unless you are talking about 100,000,001 calls, then the difference is down in the noise, and even at 100,000,001 calls it is on the order of a couple of seconds (unless you are still using an 8086 processor). Try it. – David C. Rankin Aug 26 '14 at 20:38
  • Ok, @DavidC.Rankin, after some time with C I've got your point. Actually, nowadays processors are faster than Atmega ones :) But I still can't agree to Farouk answer, because allocated memory isn't guaranteed to be contiguous as I wanted. – python Sep 14 '14 at 03:13