为什么我的代码没有限制?

时间:2013-12-24 19:03:01

标签: c arrays memory

那是我的代码:

#include<stdio.h>

int main()
{
    int vet[10], i;

    for(i=30; i<=45; i++)
    {
        scanf("%d", &vet[i]);
    }

    for(i=30; i<=45; i++)
        printf(" %d ", vet[i]);

    for(i=30; i<=45; i++)
        printf(" %x", &vet[i]);

    return 0;
}

我在内存上只声明了10个int类型的位置,但是我得到了更多,所以发生了什么? 这是一个内存溢出?

并且类型%x正确打印内存地址?

输入是:

1
2
3
4
5
6
7
8
9
10   /*It was to be stoped right here !?*/
11
12
13
14
15
16

并返回:

1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  /*I put space to indent*/

22ff6c 22ff70 22ff74 22ff78 22ff7c 22ff80 22ff84 22ff88 22ff8c 22ff90 22ff94 22ff98     22ff9c 22ffa0 22ffa4 22ffa8

7 个答案:

答案 0 :(得分:7)

当您访问数组以进行读取或写入时,C语言不会检查边界。程序作者应该确保程序只访问有效的数组元素。

在这种情况下,您将值写入已声明数组的内存地址。虽然在这种情况下你有时可能会遇到分段违规(SIGSEGV),但你可能只是“幸运” - 真的,不幸 - 并且在运行时没有遇到任何问题。

答案 1 :(得分:3)

C不强制执行数组边界。保持在限制范围内是你用这种语言的责任 - 它会让你做出明显错误的事情,但它可能会在运行时崩溃。

答案 2 :(得分:3)

C语言不仅没有检查数组大小的数组访问限制,这解释了为什么你成功写入数组15次,但是C也没有将你的范围转换为45到45的机制进入阵列的前10个(或15个?)元素的范围。

所以,你真的试图写入数组vet的第31到第46个元素,它只有10个元素。

答案 3 :(得分:2)

C不对数组进行边界检查,并且您正在访问一个超出范围的数组。数组中可能的有效索引为[0,9],但您正在访问[30,45]

您应该修改代码以仅访问有效索引:

int SIZE = 10;
int vet[SIZE]; 

//...

// not for( i = 30; i <= 45; i++ )
for( i = 0; i < SIZE; ++i ) { /* ... */ }

答案 4 :(得分:2)

C非常乐意让您通过您设置的边界读取和写入数组(在本例中为10)。

阅读超过限制只会给你垃圾;写过去它会做各种疯狂的事情,并且通常会使程序崩溃(或者,如果你运气不好,则覆盖你的整个硬盘)。

你很幸运这个程序,但你不应该继续这样做。在C中,您有责任自己强制执行数组的限制。

答案 5 :(得分:2)

int vet[10]在内存中声明一个包含十个整数的块。可以通过vet[0]vet[9]访问这些内存位置。通过vet对内存的任何其他访问都是未定义的行为。绝对任何东西都可以在那个内存中,你很容易破坏程序执行的其余部分。编译器相信你比你正在做的更清楚。

正如@NigelHarper正确指出的那样,%p是打印指针的官方方式。它以十六进制打印。指针可以用十进制打印,但数字本身没有意义。十六进制使打印更简洁,同样容易看到从一个地址到下一个地址的差异。

也可以使用%x来打印指针,因为所有操作都是取值并以十六进制格式打印。

答案 6 :(得分:0)

C语言不支持检查超出范围的数组访问。在c ++中,如果您尝试访问超出绑定的数组内存位置,它将生成分段错误,导致您的进程终止。因为,C不允许它,这是预期的行为。