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++ 这里到底发生了啥? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

这里发生了啥你不能比较 C++ 中的 if(mychar1 == 'ä' || mychar2 == 'Ä') 吗?

android“强制关闭”内存到底发生了啥

c++中扩展欧几里得算法的递归到底发生了啥?

有人可以解释一下这里发生了啥吗?存在普遍量化

这里发生了啥?核心数据/iCloud

这里的 useRef 内部发生了啥?