问题标签 [undefined-behavior]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
7 回答
2113 浏览

c++ - 为什么我不应该在“删除这个”之后尝试使用“这个”值?

本段 C++ FAQdelete this中讨论了构造的用法。列出了 4 个限制。

限制 1 到 3 看起来很合理。但是为什么限制 4 我“不能检查它,将它与另一个指针进行比较,将它与 NULL 进行比较,打印它,强制转换它,用它做任何事情”?

我的意思this是另一个指针。为什么我不能调用reinterpret_cast它来输出它的值?intprintf()

0 投票
5 回答
570 浏览

c - 添加到指针时出现意外结果

有人告诉我这段代码打印出 29。这是为什么呢?

0 投票
10 回答
8871 浏览

c++ - 将 new[] 与 delete 配对怎么可能只导致内存泄漏?

首先,根据 C++ 标准,使用delete任何分配的东西都是未定义的行为。new[]

在 Visual C++ 7 中,这种配对可能导致两种后果之一。

如果类型 new[]'ed 具有微不足道的构造函数和析构函数 VC++ 只是使用new而不是new[]使用delete该块工作正常 -new只需调用“分配内存”,delete只需调用“空闲内存”。

如果类型 new[]'ed 具有非平凡的构造函数或析构函数,则上述技巧无法完成 - VC++7 必须调用正确数量的析构函数。所以它在数组前面加上一个size_t存储元素的数量。现在返回的地址new[]指向第一个元素,而不是块的开头。因此,如果delete使用它只调用第一个元素的析构函数,并且调用“空闲内存”,其地址与“分配内存”返回的地址不同,这会导致 HeapFree() 内部出现一些错误指示,我怀疑这是指堆腐败。

然而,到处都可以读到使用deleteafternew[]会导致内存泄漏的错误语句。我怀疑任何大小的堆损坏都比仅对第一个元素调用析构函数并且可能未调用的析构函数没有释放堆分配的子对象这一事实重要得多。

delete使用after怎么new[]可能只导致某些 C++ 实现的内存泄漏?

0 投票
6 回答
5166 浏览

c++ - 在 C++ 中,堆分配的对象可以是 const 吗?

在 C++ 中,可以声明堆栈分配的对象const

之后尝试在此类对象上调用非常量方法是未定义的行为:

堆分配的对象会const产生同样的后果吗?我的意思是有可能是以下情况:

也是未定义的行为吗?

0 投票
13 回答
16896 浏览

c++ - C++ 删除 - 它删除了我的对象,但我仍然可以访问数据?

我编写了一个简单的、有效的俄罗斯方块游戏,每个块都作为类单块的实例。

我有一个扫描完整行的函数,并遍历块的链接列表,删除相关的块并重新分配 ->next 指针。

游戏正常运行,块被正确删除,一切正常运行。但是,经过检查,我仍然可以访问已删除数据的随机位。

如果我在删除后打印每个已删除的单块“x”值,其中一些返回随机垃圾(确认删除),其中一些返回 222,告诉我即使调用了析构函数,数据实际上并没有从中删除堆。许多相同的试验表明,没有正确删除的总是相同的特定块。

结果:

是否能够从超出预期的坟墓中访问数据?

对不起,如果这有点啰嗦。

0 投票
7 回答
5979 浏览

c++ - 在 const 对象上间接调用非常量函数

给定以下代码:

以下是否使用定义的行为?

我问是因为我正在使用类注册表,并且因为我不直接修改f它会很好const,但是稍后f会被注册表间接修改。

编辑:通过定义的行为,我的意思是:对象是否放置在一些只能写入一次的特殊内存位置?只读内存是不可能的,至少在 C++1x 的 constexpr 之前是这样。例如,常量原始类型(通常)被放置在只读内存中,并且对其执行 aconst_cast可能会导致未定义的行为,例如:

0 投票
1 回答
365 浏览

c++ - stl::deque 的 insert(loc, val) - deque 末尾与其他位置的行为不一致?

使用http://www.cppreference.com/wiki/stl/deque/insert作为参考,我将值插入到特定位置的双端队列中。

例如,如果双端队列 A 是:

使用指向 d 的迭代器,我可以:

并且 iter 仍然指向 d。但是,当 iter 指向 g 时,最后一个元素:

但现在 iter 指向 f!!

我目前的解决方法是:

我没有再次测试过这个或任何东西,花了这么多时间跟踪一个错误,只是为了在所有地方发现 insert() 的不一致行为,这很烦人。

与在任何其他位置相比,为什么 insert() 在最后的行为不同?还是我做错了什么?

0 投票
14 回答
2774 浏览

c++ - C ++中的内存泄漏“未定义行为”类问题吗?

事实证明,许多看起来很无辜的东西在 C++ 中是未定义的行为。例如,一旦一个非空指针被打印delete出来,甚至打印出该指针值是未定义的行为

现在内存泄漏肯定很糟糕。但是他们是什么类的情况——定义的、未定义的或其他什么类的行为?

0 投票
4 回答
588 浏览

c++ - 代码的有效性

考虑以下代码:

当地社区对此进行了讨论,代码是否有效(我应该提及它的名字吗?)。一个人说它调用了 UB,因为它违反了

C++ 标准($5.7/5 [expr.add])

“如果指针操作数和结果都指向同一个数组对象的元素,或者超过数组对象的最后一个元素,则评估不应产生溢出;否则,行为未定义。”

但我看不出代码有什么问题,代码对我来说完全没问题。

所以,我只想知道这段代码是否有效?我错过了什么吗?

0 投票
4 回答
513 浏览

c++ - 限制未定义行为引起的混乱?

正如我从阅读中了解到的那样,未定义行为是在编译时给编译器留下了几个不同的替代方案的结果。但是,这是否意味着如果要遵循严格的编码实践(例如将每个赋值和每个相等放在单独的语句中,适当的调试和注释),那么在查找未定义的来源时就不应该构成重大问题-行为。

此外,对于出现的每个错误,如果您识别代码,您应该知道可以使用哪些语句代替该特定语句,对吗?

编辑:我对你写了你不想写的代码的地方不感兴趣。我对数学逻辑合理的代码无法工作的示例感兴趣。

此外,我认为“良好的编码实践”是每隔几行提供信息丰富的注释、适当的缩进和定期调试转储。