数组的定义
数组定义的格式:
数据类型 变量名[常亮]; //为什么不能使变量?
//因为在声明的时候 编译器需要知道数组的长度,分配相应大小的内存
数组的初始化
-
方式1:
int arr[10] = {0,0,0,0,0,0,0,0,0,0};
-
方式2:
int arr[] = {1,2,3,4,5,6,7,8,9,10};
对应汇编
#include "stdafx.h"
int main(int argc, char* argv[])
{
int age[10] = {1,2,3,4,5,6,7,8,9,10};
return 0;
}
8: int age[10] = {1,2,3,4,5,6,7,8,9,10};
00401028 C7 45 D8 01 00 00 00 mov dword ptr [ebp-28h],1
0040102F C7 45 DC 02 00 00 00 mov dword ptr [ebp-24h],2
00401036 C7 45 E0 03 00 00 00 mov dword ptr [ebp-20h],3
0040103D C7 45 E4 04 00 00 00 mov dword ptr [ebp-1Ch],4
00401044 C7 45 E8 05 00 00 00 mov dword ptr [ebp-18h],5
0040104B C7 45 EC 06 00 00 00 mov dword ptr [ebp-14h],6
00401052 C7 45 F0 07 00 00 00 mov dword ptr [ebp-10h],7
00401059 C7 45 F4 08 00 00 00 mov dword ptr [ebp-0Ch],8
00401060 C7 45 F8 09 00 00 00 mov dword ptr [ebp-8],9
00401067 C7 45 FC 0A 00 00 00 mov dword ptr [ebp-4],0Ah
//因为在函数内。所以分配在堆栈中,这里使用的就是ebp寻址
数组的内存分配
分辨定义char/short/int
类型的数组,观察ESP中减少了多少
前面讲过,在32位操作系统中
char
类型分配的空间仍然是32位 跟int一样本机宽度,在计算机系统中32位系统中,一次处理4字节速度最快。所以处理一次性处理本机宽度的数据最快
本机32位也就是4字节,所以会出现4字节对齐的情况
//本机宽度 32 4字节 4字节对齐
char age[10];
//4c - 40 =C 也就是十进制的12,char占用一个字节,需要10个字节,但是因为4字节对齐,所以分配的就是12个字节
short age[10];
//54 - 40 = 14 也就是十进制的 20 ,short占用两个字节,需要20个字节,20个字节正好符合4字节对齐,所以分配的就是20个字节
存入、读取数组中的值
读取数组中的某个成员的内容:
int x = 数组名[表达式]:
//读出数据
int a = age[0];
int b = age[1];
给数组中某个成员赋值:
数组名[表达式] = 表达式;
age[1] = 1;
特别说明
使用数组成员的时候[]可以使表达式。
c = arr[1];
c = arr[x];
数组的越界访问
int arr[10];
arr[10] = 100; //可以吗?结果会怎么样?
请看下面 缓冲区溢出
缓冲区溢出
#include "stdafx.h"
void Fun()
{
while(1)
{
printf("我怎么会被调用列?\n");
}
}
int main(int argc, char* argv[])
{
int arr[8];
arr[9] = (int)&Fun;
return 0;
}
原理:
利用数组越界 造成缓冲区溢出
经过观察我们发现,这里的数组越界访问,造成了堆栈中返回地址被篡改为 Fun函数的地址,一旦执行到ret指令后,程序将会跳转到fun函数往下执行,也就进入了死循环