为什么我 运行 下面的代码没有报错

Why don't I get an error when I run the following code

我是 运行 下面的代码,我在其中声明了一个动态二维数组,然后继续在比实际为动态数组分配的列数更高的列索引处分配值。然而,当我这样做时,代码运行完美,我没有收到错误,我相信我应该得到。

 void main(){


        unsigned char **bitarray = NULL;
        bitarray = new unsigned char*[96];

        for (int j = 0; j < 96; j++)
        {
                bitarray[j] = new unsigned char[56];
            if (bitarray[j] == NULL)
            {
                cout << "Memory could not be allocated for 2D Array.";
                return;// return if memory not allocated
            }
        }

        bitarray[0][64] = '1';
        bitarray[10][64] = '1';

        cout << bitarray[0][64] << " " << bitarray[10][64];

        getch();
        return;
    }

The link to the output I get is here(实际上赋值准确,不知道为什么)。

在 C++ 中,越界访问缓冲区会调用未定义的行为(不是您预期的陷阱错误)。

C++ 规范将术语未定义行为定义为:

behavior for which this International Standard imposes no requirements.

在您的代码中,两者都

    bitarray[0][64] = '1';
    bitarray[10][64] = '1';

正在越界访问内存。即,这些内存位置是 "invalid"。访问无效内存调用 undefined behaviour.

访问冲突错误或分段错误是 UB 的众多可能结果之一。没有任何保证。

来自wiki page for segmentation fault,

On systems using hardware memory segmentation to provide virtual memory, a segmentation fault occurs when the hardware detects an attempt to refer to a non-existent segment, or to refer to a location outside the bounds of a segment, .....

所以,也许,只是也许bitarray[0][64]的内存区域在分配的页面(段)内,程序可以访问(但无论如何无效) ,在这种非常特殊的情况下。这并不意味着它将永远如此。

也就是说,void main() 不是 main() 函数的正确签名。 main() 的推荐 (C++11,§3.6.1) 签名是 int main(void).

C++11 引入了 std::array 并且方法 at() 提供了越界检查。