C++ 这里到底发生了啥? [关闭]
Posted
技术标签:
【中文标题】C++ 这里到底发生了啥? [关闭]【英文标题】:C++ What exactly happened here? [closed]C++ 这里到底发生了什么? [关闭] 【发布时间】:2021-08-09 15:20:10 【问题描述】:在编写程序时,我在动态数组中发现了一个意外行为。在我做了一些测试后,我最终得到了这段代码。
#include <iostream>
unsigned long index;
template<typename T>
class A
public:
void Set()
T* target = new T[index];
for (unsigned int i = 0; i < index; i++)
target[i] = i;
this->value_ = target;
index++;
T* value_;
;
int main()
A<int> test;
test.Set();
std::cout << test.value_[0] << '\n';
test.Set();
std::cout << test.value_[1];
返回以下值:
11104472
11075776
每次执行程序时值都会发生变化,但是,我认为输出将是“0”和“1”。我想它们是内存地址,但为什么程序返回它们而不是预期的输出?
【问题讨论】:
问问自己:当我做T* target = new T[index];
时,index
的值是多少?我现在有多大的数组?
你可能会这么想,但是一旦你进入了未定义的行为领域,就没有回头路了。就像加利福尼亚酒店那样;)
@Salty27:第二个也是一样。现在您正在分配一个大小为 1 的数组,并访问第二个元素。哎呀。
index
自动初始化为零:您都在访问数组末尾之外的一个元素。在第一个 Set
处,您创建了一个零元素数组,但随后您访问了第一个元素 ([0]
)。下一次,您创建一个包含一个元素的数组,然后访问第二个元素 ([1]
)。 (另外,你永远不会 delete[]
你创建的东西,每次调用 Set
时都会泄漏内存。)
@Salty27:或者将index
的增量移动到Set()
的顶部。
【参考方案1】:
看看index
会有哪些值。它用 0 初始化。所以在第一个 test.Set();
中,您创建了一个长度为 0 的数组。甚至稍后再阅读它是错误的,并导致所谓的未定义行为。在 set 的第二次调用中,index 的值为 1,因此您创建了一个长度为 1 的数组,并将位置 0 上的第一个元素正确初始化为 0,但您随后尝试打印出 test.value_[1]
,这不是第一个元素,但第二个。记住数组索引从 0 开始。所以这也是越界读取,即错误的行为会受到随机行为的惩罚。
【讨论】:
以上是关于C++ 这里到底发生了啥? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章