Question about address values and pointer increment?


Let's say that I have a code like below

#include <stdio.h>

int main(void)
    char char_array[5] = {'a', 'b', 'c', 'd', 'e'};
    int int_array[5] = {1, 2, 3, 4, 5};
    int i;

    char *char_ptr;
    int *int_ptr;

    char_ptr  = char_array;
    int_ptr = int_array;

    for(i = 0; i < 5; i++){
        printf("[char_ptr]For %p address pointing to %c value\n", char_ptr, *char_ptr);
        char_ptr +=1;

    for(i = 0; i < 5; i++){
        printf("[int_ptr]For %p address pointing to %d value\n", int_ptr, *int_ptr);
        int_ptr += 1;

    return 0;

Then the output will be

[char_ptr]For 0xbf7fc37f address pointing to a value
[char_ptr]For 0xbf7fc380 address pointing to b value
[char_ptr]For 0xbf7fc381 address pointing to c value
[char_ptr]For 0xbf7fc382 address pointing to d value
[char_ptr]For 0xbf7fc383 address pointing to e value
[int_ptr]For 0xbf7fc368 address pointing to 1 value
[int_ptr]For 0xbf7fc36c address pointing to 2 value
[int_ptr]For 0xbf7fc370 address pointing to 3 value
[int_ptr]For 0xbf7fc374 address pointing to 4 value
[int_ptr]For 0xbf7fc378 address pointing to 5 value

My question here is why is the increasement of the address different in int_ptr even though I only added only 1 to the address? I know that is a int variable which is a size of 4 bytes but I'm wondering how the program added 4 to the address even though I only added one to it.

Thank you

+addition sorry for the confusion that I made from tagging reverse engineering, I was using gdb to look at some asm codes in order to answer my question.

  0x00001199 <+0>:     lea    ecx,[esp+0x4]
   0x0000119d <+4>:     and    esp,0xfffffff0
   0x000011a0 <+7>:     push   DWORD PTR [ecx-0x4]
   0x000011a3 <+10>:    push   ebp
   0x000011a4 <+11>:    mov    ebp,esp
   0x000011a6 <+13>:    push   ebx
   0x000011a7 <+14>:    push   ecx
   0x000011a8 <+15>:    sub    esp,0x30
   0x000011ab <+18>:    call   0x10a0 <__x86.get_pc_thunk.bx>
   0x000011b0 <+23>:    add    ebx,0x2e50
   0x000011b6 <+29>:    mov    DWORD PTR [ebp-0x19],0x64636261
   0x000011bd <+36>:    mov    BYTE PTR [ebp-0x15],0x65
   0x000011c1 <+40>:    mov    DWORD PTR [ebp-0x30],0x1
   0x000011c8 <+47>:    mov    DWORD PTR [ebp-0x2c],0x2
   0x000011cf <+54>:    mov    DWORD PTR [ebp-0x28],0x3
   0x000011d6 <+61>:    mov    DWORD PTR [ebp-0x24],0x4
   0x000011dd <+68>:    mov    DWORD PTR [ebp-0x20],0x5
   0x000011e4 <+75>:    lea    eax,[ebp-0x19]
   0x000011e7 <+78>:    mov    DWORD PTR [ebp-0x10],eax
   0x000011ea <+81>:    lea    eax,[ebp-0x30]
   0x000011ed <+84>:    mov    DWORD PTR [ebp-0x14],eax
   0x000011f0 <+87>:    mov    DWORD PTR [ebp-0xc],0x0
   0x000011f7 <+94>:    jmp    0x1220 <main+135>
   0x000011f9 <+96>:    mov    eax,DWORD PTR [ebp-0x10]
   0x000011fc <+99>:    movzx  eax,BYTE PTR [eax]
   0x000011ff <+102>:   movsx  eax,al
   0x00001202 <+105>:   sub    esp,0x4
   0x00001205 <+108>:   push   eax
   0x00001206 <+109>:   push   DWORD PTR [ebp-0x10]
   0x00001209 <+112>:   lea    eax,[ebx-0x1ff8]
   0x0000120f <+118>:   push   eax
   0x00001210 <+119>:   call   0x1030 <printf@plt>
   0x00001215 <+124>:   add    esp,0x10
   0x00001218 <+127>:   add    DWORD PTR [ebp-0x10],0x1
   0x0000121c <+131>:   add    DWORD PTR [ebp-0xc],0x1
   0x00001220 <+135>:   cmp    DWORD PTR [ebp-0xc],0x4
   0x00001224 <+139>:   jle    0x11f9 <main+96>
   0x00001226 <+141>:   mov    DWORD PTR [ebp-0xc],0x0
   0x0000122d <+148>:   jmp    0x1252 <main+185>
   0x0000122f <+150>:   mov    eax,DWORD PTR [ebp-0x14]
   0x00001232 <+153>:   mov    eax,DWORD PTR [eax]
   0x00001234 <+155>:   sub    esp,0x4
   0x00001237 <+158>:   push   eax
   0x00001238 <+159>:   push   DWORD PTR [ebp-0x14]
   0x0000123b <+162>:   lea    eax,[ebx-0x1fc8]
   0x00001241 <+168>:   push   eax
   0x00001242 <+169>:   call   0x1030 <printf@plt>
   0x00001247 <+174>:   add    esp,0x10
   0x0000124a <+177>:   add    DWORD PTR [ebp-0x14],0x4
   0x0000124e <+181>:   add    DWORD PTR [ebp-0xc],0x1
   0x00001252 <+185>:   cmp    DWORD PTR [ebp-0xc],0x4
   0x00001256 <+189>:   jle    0x122f <main+150>
   0x00001258 <+191>:   mov    eax,0x0
   0x0000125d <+196>:   lea    esp,[ebp-0x8]
   0x00001260 <+199>:   pop    ecx
   0x00001261 <+200>:   pop    ebx
   0x00001262 <+201>:   pop    ebp
   0x00001263 <+202>:   lea    esp,[ecx-0x4]
   0x00001266 <+205>:   ret    
asked on Stack Overflow Dec 14, 2019 by user12534247 • edited Dec 14, 2019 by jww

1 Answer


Most modern CPUs are byte addressable. That means that each memory address refers to a single byte. Thus, for every char (which occupies 1 byte) in memory, you only need one address.

If you're working with a contiguous array of ints (which take up 4 bytes on most machines), however, your addresses will have to "hop" 4 by 4, because there are 4 bytes that memory needs to address and thus 4 memory addresses are taken.

In your example:

0xbf7fc368 refers to the first byte of the first `int`.
0xbf7fc369 refers to the second byte of the first `int`.
0xbf7fc36a refers to the third byte of the first `int`.
0xbf7fc36b refers to the fourth byte of the first `int`.
0xbf7fc36c refers to the first byte of the second `int`.
... and so on.
answered on Stack Overflow Dec 14, 2019 by Saucy Goat • edited Dec 14, 2019 by Saucy Goat

User contributions licensed under CC BY-SA 3.0