c++ - C++ 这里到底发生了什么?
问题描述
在做一个程序时,我想出了动态数组中的一个意外行为。在我做了一些测试之后,我最终得到了这段代码。
#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”。我想它们是内存地址,但为什么程序返回它们而不是预期的输出?
解决方案
看看index
会有哪些值。它用 0 初始化。所以首先test.Set();
创建一个长度为 0 的数组。甚至稍后再阅读它是错误的,并导致所谓的未定义行为。在 set 的第二次调用中,index 的值为 1,因此您创建了一个长度为 1 的数组,并将位置 0 上的第一个元素正确初始化为 0,但是您随后尝试打印出test.value_[1]
哪个不是第一个元素,而是第二。记住数组索引从 0 开始。所以这也是一个越界读取,即错误的行为会受到随机行为的惩罚。
推荐阅读
- javascript - Function-binding with super keyword in javascript
- for-loop - 循环的增量表达式
- c++ - 动态数组实际上是动态的吗?
- julia - 为顶点添加自定义名称
- r - 为什么在使用 gganimate() 时会出现一些断断续续的颜色(绿色)?
- r - 给定计数,我如何在 R 中使用列联表和 Fisher 测试
- google-apps-script - 应用程序脚本 - 谷歌表,需要用户表单的帮助
- git - 如何强制 git 请求密码以设置个人访问令牌?
- ruby-on-rails - RSpec找不到Kaminari的方法
- django - Django ImageField 模板注入