问题标签 [assign]
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.
linux - 来自 libstdc++.so.6 的 std::string::assign() 方法中奇怪的 SIGSEGV 分段错误
我的程序最近在运行时遇到了一个奇怪的段错误。 我想知道是否有人以前遇到过这个错误以及如何修复它。 这是更多信息:
基本信息:
- CentOS 5.2,内核版本为 2.6.18
- g++ (GCC) 4.1.2 20080704 (红帽 4.1.2-50)
- CPU:英特尔 x86 系列
- libstdc++.so.6.0.8
- 我的程序将启动多个线程来处理数据。段错误发生在其中一个线程中。
- 虽然它是一个多线程程序,但段错误似乎发生在本地 std::string 对象上。稍后我将在代码片段中展示这一点。
- 该程序使用-g、-Wall 和-fPIC 编译,没有-O2 或其他优化选项。
核心转储信息:
请注意,段错误从basic_string::operator=()开始。
相关代码:( 我展示了比可能需要的更多的代码,请暂时忽略编码风格的东西。)
这是这个 FormatTimeStamp 方法的原型:
我认为这样的字符串赋值操作应该是一种常用的,但我就是不明白为什么会出现段错误。
我调查的内容:
我在网上搜索了答案。我看着这里。回复说尝试使用定义的 _GLIBCXX_FULLY_DYNAMIC_STRING 宏重新编译程序。我试过了,但崩溃仍然发生。
我也看过这里。它还说用_GLIBCXX_FULLY_DYNAMIC_STRING重新编译程序,但作者似乎正在处理我的另一个问题,因此我认为他的解决方案不适合我。
更新于 2011 年 8 月 15 日
这是这个 FormatTimeStamp 的原始代码。我知道编码看起来不太好(例如,幻数太多..),但让我们首先关注崩溃问题。
更新于 2011 年 8 月 19 日
这个问题终于得到解决和解决。事实上,FormatTimeStamp() 函数与根本原因无关。段错误是由本地字符缓冲区的写入溢出引起的。
可以使用以下更简单的程序重现此问题(请暂时忽略某些变量的错误命名):
(用“g++ -Wall -g main.cpp”编译)
在继续之前,我们应该记住以下两个事实:1)。我的机器是 Intel x86 机器,所以它使用 Little Endian 规则。因此,对于一个 int 类型的变量“m”,例如,其值为 10,它的内存布局可能是这样的:
2)。上面的程序在主线程中运行。说到overflow_it()函数,线程栈中的变量布局是这样的(只显示了重要的变量):
我的分析:
1)。m 是 overflow_it() 中的一个计数器,其值在每个 for 循环中递增 1,并且其最大值不应大于 6。因此它的值可以完全存储在 m(byte#1) 中(记住它是 Little Endian)恰好是 temp 3。
2)。在错误行中:当 t 是 3 位整数时,例如 109,则 sprintf() 调用将导致缓冲区溢出,因为将数字 109 序列化为字符串“109”实际上需要 4 个字节:'1' , '0', '9' 和终止符 '\0'。因为 temp[] 只分配了 3 个字节,所以最终的 '\0' 肯定会被写入 temp 3,这只是 m(byte#1),不幸的是它存储了 m 的值。因此,m 的值每次都重置为 0。
3)。然而,程序员的期望是,overflow_it() 中的 for 循环只会执行 6 次,每次 m 加 1。因为 m 总是重置为 0,所以实际循环时间远不止 6 次。
4)。我们看一下overflow_it()中的变量i:每次执行for循环,i的值加2,访问A15Result[i]。但是,如果您编译并运行该程序,您会看到 i 值最终加起来为 24,这意味着 overflow_it() 将数据写入从 A15Result[0] 到 A15Result[23] 的字节。请注意,对象 str 仅落后于 A15Result[0] 16 个字节,因此 overflow_it() 已“扫过” str 并破坏了它的正确内存布局。
5)。我认为 std::string 的正确使用,因为它是一个非 POD 数据结构,取决于实例化的 std::string 对象必须具有正确的内部状态。但是在这个程序中,str的内部布局已经被外部强行改变了。这应该就是为什么 assign() 方法调用最终会导致段错误的原因。
2011 年 8 月 26 日更新
在我之前 2011 年 8 月 19 日的更新中,我说过段错误是由对本地 std::string 对象的方法调用引起的,该对象的内存布局已被破坏,因此成为“被破坏”的对象。这不是一个“总是”真实的故事。考虑下面的 C++ 程序:
Hello() 调用会成功。即使您为 pa 分配了一个明显错误的指针,它也会成功。原因是:根据 C++ 对象模型,类的非虚拟方法不驻留在对象的内存布局中。C++ 编译器将 A::Hello() 方法转换为诸如 A_Hello_xxx(A * const this, ...) 之类的东西,它可能是一个全局函数。因此,只要您不对“this”指针进行操作,事情就会顺利进行。
这一事实表明,“坏”对象不是导致 SIGSEGV 段错误的根本原因。assign() 方法在 std::string 中不是虚拟的,因此“坏”的 std::string 对象不会导致段错误。一定有其他原因最终导致了段错误。
我注意到段错误来自 __gnu_cxx::__exchange_and_add() 函数,所以我在这个网页中查看了它的源代码:
__exchange_and_add() 最终调用了 __sync_fetch_and_add()。根据这个网页, __sync_fetch_and_add() 是一个 GCC 内置函数,其行为如下:
就在那里!传入的 ptr 指针在这里被取消引用。在 08/19/2011 程序中,ptr 实际上是 assign() 方法中“坏”std::string 对象的“this”指针。正是此时的取消引用实际上导致了 SIGSEGV 分段错误。
我们可以使用以下程序对此进行测试:
map - 在golang中分配给地图
在下面的代码片段中,我做错了什么?
编译给了我这个错误:
双母羊 T eff?
delphi - 将对象引用分配给变量
我有一个关于assign here的问题,我想知道
- 是否
Assign
复制整个对象并且 - 我想知道是否
FTEA.Objects[0]
也被释放。
我想复制一份,FTEA.Objects[0]
当我免费时ObjCur
,我不打算免费FTEA.Objects[0]
- 不确定这样做的正确方法,需要你的帮助,谢谢:
jquery - 如何使用 Jquery 从另一个分配文件输入值?
我有一些像这样的元素:
我的问题是:是否可以使用 jquery 将“假”输入的值分配给“真实”输入?这样当我点击提交按钮时,“真实”文件输入将被上传。
r - 在一行中在 LHS 上分配多个新变量
我想在 R 的一行中分配多个变量。可以做这样的事情吗?
通常我想在一行中分配大约 5-6 个变量,而不是多行。有替代方案吗?
r - 将名称从一个列表分配给另一个
我有一堆动态创建的回归存储在一些名为regressions
. 现在我想有效地重命名它们的系数。到目前为止,我所拥有的是这个有效的循环:
在函数的帮助下,我已经尝试了很长一段时间来更普遍地完成这项工作,因为这不是我拥有的唯一回归列表。但是我无法让其他任何工作。这里主要基于 lapply 的其他一些尝试:
另一种尝试是编写一个带有 for 循环的函数,该循环在内部也可以作为 print 显示,但不会全局分配名称(存储回归列表的位置)。
啊,让我休息一下。
asp.net - asp.net 4.0 c# 分配文本值时,aspx和code之间有什么区别吗
这是分配 aspx.cs 背后的代码
这是aspx分配
这两者之间有什么性能差异吗?
xcode - XCode:检查并将拆分字符串值分配给 textField
所以我一直在尝试对此进行测试;基本上我有一个名为 rawData.txt 的文本文件,它看起来像这样:
我想拆分行,然后拆分每一行并检查第一部分(9位数字),但它似乎根本不起作用(我的窗口关闭)这段代码有什么问题吗?
c - 在指针中赋值的麻烦
假设我想给一个指针赋值。
可能吗?
我很困惑。请让我知道。我检查了所有行,但只有指针分配似乎是错误的。所以,这里是问题代码(它可能很复杂,但我正在通过评论简化它,请参阅评论):
在主要功能内部:
python - 如何在 Python 中使用索引作为键?
我有一个清单:v = [1,2,2,3]
。我想将此列表用作键。我可以“手动”完成:
但
x[v] = 7
不起作用。做我需要做的最简单的方法是什么?
添加
我把解决方案想象成这样: