You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何访问Container的_arr[3]未抛出异常?构造函数的影响

What's Going On With Your Container Class?

Let's break this down step by step—this is a classic case of undefined behavior causing confusing results, so let's unpack it.

Why Your Original Code Doesn't Throw an Exception

First things first: C++ does not guarantee that array out-of-bounds access will throw an exception. This is classified as undefined behavior—the standard leaves the outcome entirely up to your compiler, operating system, and runtime environment.

In your code, the Container constructor allocates an array of 3 ints (since d=3 by default), which means valid indices are 0, 1, and 2. Your loop accesses index 3, but why doesn't it crash? Chances are, the memory immediately after your allocated array is still within your program's address space—maybe the memory allocator added a little extra padding, or that chunk of memory hasn't been claimed by another part of your program. So writing to and reading from _arr[3] just works... for now. It's totally luck-based, not something you can ever rely on.

Why Removing the Constructor Causes an Exception

When you delete your custom constructor, the compiler generates a default constructor for Container. This default constructor does not initialize the _arr pointer at all—it leaves it as a "wild pointer" pointing to a random, invalid memory address.

When you try to access _arr[index] with a wild pointer, you're almost certainly hitting memory your program doesn't have permission to touch. That triggers a memory access violation (like a segmentation fault on Linux/macOS, or an access violation on Windows), which the runtime will usually present as an exception or crash.

Why You See the Output "012"

Let's walk through your loop line by line to make sense of the output:

  • i=1: You write 1 to _arr[1] (a valid index). When you read it back, the X constructor takes 1 and outputs 1-1=0.
  • i=2: You write 2 to _arr[2] (another valid index), read it back, and X outputs 2-1=1.
  • i=3: You write 3 to _arr[3] (out of bounds, but accessible by chance). Reading it back gives you 3, so X outputs 3-1=2.
    Stick those outputs together, and you get 012.

How to Fix This (And Get Predictable Bounds Checking)

If you want to enforce bounds checks and get a reliable exception when accessing invalid indices, add the checks manually:

#include <stdexcept> // For std::out_of_range

template <class T, int d=3>
class Container {
T* _arr;
public:
Container():_arr(new T[d]){ }
~Container() { delete[] _arr; } // Don't forget to free allocated memory!

void setItemAtIndex(T item, int index) {
    if (index < 0 || index >= d) {
        throw std::out_of_range("Index is out of bounds");
    }
    _arr[index] = item;
}

X getItemAtIndex(int index) {
    if (index < 0 || index >= d) {
        throw std::out_of_range("Index is out of bounds");
    }
    return _arr[index];
}
};

Even better: Ditch raw pointers entirely and use std::vector<T>—it handles memory management automatically, and its built-in at() method throws std::out_of_range for invalid indices out of the box.

内容的提问来源于stack exchange,提问作者tempt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:11:48