假设我有如下代码
#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;
}
那么输出将是
[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
我的问题是,为什么 int_ptr 中的地址增加量不同,尽管我只向地址添加了 1?我知道这是一个 int 变量,大小为 4 个字节,但我想知道程序如何将 4 添加到地址,即使我只添加了 1。
谢谢
+添加 抱歉,我在标记逆向工程时造成了困惑,我正在使用 gdb 查看一些 asm 代码来回答我的问题。
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
最佳答案
大多数现代 CPU 都是字节寻址的。这意味着每个内存地址引用一个字节。因此,对于内存中的每个 char
(占用 1 个字节),您只需要一个地址。
但是,如果您正在使用连续的 int
数组(在大多数计算机上占用 4 个字节),您的地址将必须 4 乘 4 进行“跳跃”,因为有内存需要寻址 4 个字节,因此占用了 4 个内存地址。
在您的示例中:
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.
关于c - 关于地址值和指针增量的问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59331984/