关于数组的越界问题

关于数组的越界问题

代码如下:

#include <stdio.h>
#include <stdlib.h>
typedef struct {
    int a[2];
    double d;
} struct_t;
double fun(int i) {
    volatile struct_t s;
    s.d = 3.14;
    s.a[i] = 1073741824; /* Possibly out of bounds */
    return s.d; /* Should be 3.14 */
}
int main(int argc, char *argv[]) {
    int i = 0;
    if (argc >= 2)
	i = atoi(argv[1]);
    double d = fun(i);
    printf("fun(%d) --> %.10f\n", i, d);
    return 0;
}

再看结果:

hxl@hxl-virtual-machine:~/桌面/task/code$ ./s 0
fun(0) --> 3.1400000000
hxl@hxl-virtual-machine:~/桌面/task/code$ ./s 1
fun(1) --> 3.1400000000
hxl@hxl-virtual-machine:~/桌面/task/code$ ./s 2
fun(2) --> 3.1399998665
hxl@hxl-virtual-machine:~/桌面/task/code$ ./s 3
fun(3) --> 2.0000006104
hxl@hxl-virtual-machine:~/桌面/task/code$ ./s 4
fun(4) --> 3.1400000000
hxl@hxl-virtual-machine:~/桌面/task/code$ ./s 5
fun(5) --> 3.1400000000
hxl@hxl-virtual-machine:~/桌面/task/code$ ./s 6
*** stack smashing detected ***: <unknown> terminated
已放弃 (核心已转储)

首先来看这段代码内容,定义了一个结构体,一个大小为2的int型数组,一个double型变量,主函数调用fun()函数,fun()函数是返回结构体中的double型变量的值,主函数打印。
再来解释下为什么会出现这种情况:
1 .结构体中先定义数组,再定义double型变量,则分配空间时先为数组分配两个元素的空间,然后再为double型变量分配。
2.当输入时,如果输入0和1时,是不会出现问题的,但是输入1以上时就可能出现错误了,因为如果输入1以上时,就是对一个没有这么大空间的数组再重新找一个地址,去储存fun(i),而重新找的一个地址,是有风险的,因为不知道这个地址有没有储存有用的信息。比如fun(2),fun(3)出现的结果就不对了,因为已经覆盖到了double变量的地址了,但是fun(4)又是正确的了,因为一个int型数组的每个元素占用4个字节,一个double型占用8个字节,而分配时先分配8个字节给数组,然后分配8个字节给double型,而fun(3),fun(4)破坏了double型变量的地址,导致结果不正确。而fun(4)是在double后面找地址,也就不会出现数据错误的现象了。
3.但是当输入6时,出现 “已放弃 (核心已转储)”,这是因为调用函数时都会有个返回地址,这个返回地址用于回到主函数,而此时的a[6]的地址恰巧破坏了这个返回地址,从而主函数中不能执行printf语句了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值