访问字符阵列中不可用的内存位置(超出范围值)

Accessing unavailable memory location in character array (Out of range value)

本文关键字:位置 范围 内存 阵列 字符 访问      更新时间:2023-10-16

我有一个代码:

#include <iostream>
using namespace std;
int main(){
    char a[5][5] = {{'x','y','z','a','v'},{'d','g','h','v','x'}};
    for(int i=0; i<2; i++){
        for(int j = 0; j<6; j++)
        {
            cout << a[i][j];
        }
    }
    return 0;
}

您可以看到第一个和第二维是或大小5个元素。使用Double for Loop的我只是在打印变量a。

的初始化的内容

int" j"的大小,随着其增加的输出变化。

为什么会发生这种情况?

指针是解决方案的吗?如果是的话?如果我们能做些什么来避免由于此不正确访问而造成的运行时间错误?

您可能会将此问题视为Java中的界外错误,严格定义了行为:您将获得ArrayIndexOutOfBoundsException,并且该程序将立即终止,除非捕获和处理例外。

在C 中,这种局限性错误是不确定的行为,这意味着允许编译器做任何愚蠢的事情,它认为可以实现最佳性能。一般而言,这导致编译器盲目执行与内置的数组访问相同的指针算术,而不管内存是否有效。

在您的情况下,由于您已经分配了25 char s的内存,因此至少在i * 5 + j >= 25之前,您将访问有效的内存(在大多数环境中(,这时可能会发生任何数量的事情:

  • 您可以从堆栈中获取垃圾数据
  • 您可以使用细分故障(Windows/Visual Studio中的访问违规(崩溃该程序
  • 循环可以拒绝以您期望终止的索引终止。

最后一个是一个令人难以置信的错误:如果进行了积极的循环优化,那么当您在代码中犯这样的错误时,您可能会得到一些非常奇怪的行为。

您写的代码几乎可以肯定发生的是第一个点:尽管您分配了25 char s的空间,但您仅定义了其中10个内容,这意味着超出前10个以外的任何访问都会调用另一种类型的访问不确定的行为(访问一个非初始化的变量(,在大多数情况下,这会导致其值在使用该变量之前的任何偶然的记忆空间中填充。

>