C语言9 数组

Asura 2018年01月02日 101次浏览

数组的定义

数组定义的格式:

数据类型 变量名[常亮]; //为什么不能使变量?
//因为在声明的时候 编译器需要知道数组的长度,分配相应大小的内存

数组的初始化

  1. 方式1:

    int arr[10] = {0,0,0,0,0,0,0,0,0,0};

  2. 方式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函数往下执行,也就进入了死循环