将取消引用的对象分配给对象会导致 seg 错误
Assignment of dereferenced object to an object causes seg fault
我有以下简单的程序作为说明:
#include <string>
using namespace std;
int main()
{
string name;
string *my_str;
name = "foo";
my_str = (string *) malloc(sizeof(*my_str));
*my_str = name; // fault line
// my_str = new(my_str) string(name); // fix
}
代码编译,但在执行过程中出现 seg 错误:
$ ./a.out
Segmentation fault (core dumped)
$ gdb -q ./a.out ./core.31114
.....
Core was generated by `./a.out'.
Program terminated with signal 11, Segmentation fault.
#0 __exchange_and_add_single (__mem=<optimized out>, __val=-1)
at /home/packages/gcc/4.7/w/gcc-4.7-4.7.2/build/x86_64-linux-gnu/libstdc++-v3/include/ext/atomicity.h:66
66 /home/packages/gcc/4.7/w/gcc-4.7-4.7.2/build/x86_64-linux-gnu/libstdc++-v3/include/ext/atomicity.h: No such file or directory.
(gdb) bt
#0 __exchange_and_add_single (__mem=<optimized out>, __val=-1)
at /home/packages/gcc/4.7/w/gcc-4.7-4.7.2/build/x86_64-linux-gnu/libstdc++-v3/include/ext/atomicity.h:66
#1 __exchange_and_add_dispatch (__mem=0xfffffffffffffff8, __val=<optimized out>)
at /home/packages/gcc/4.7/w/gcc-4.7-4.7.2/build/x86_64-linux-gnu/libstdc++-v3/include/ext/atomicity.h:83
#2 std::string::_Rep::_M_dispose (this=0xffffffffffffffe8, __a=...)
at /home/packages/gcc/4.7/w/gcc-4.7-4.7.2/build/x86_64-linux-gnu/libstdc++-v3/include/bits/basic_string.h:242
#3 0x00007fbab7a5ff06 in _M_grab (__alloc1=..., this=<optimized out>, __alloc2=...)
at /home/packages/gcc/4.7/w/gcc-4.7-4.7.2/build/x86_64-linux-gnu/libstdc++-v3/include/bits/basic_string.h:226
#4 _M_grab (__alloc2=..., __alloc1=..., this=<optimized out>)
at /home/packages/gcc/4.7/w/gcc-4.7-4.7.2/build/x86_64-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:244
#5 std::string::assign (this=0x99a040, __str=...) at /home/packages/gcc/4.7/w/gcc-4.7-4.7.2/build/x86_64-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:251
#6 0x00000000004008b3 in main () at ./strassign.cc:12
我知道问题的解决方法(用字符串"fix"注释的行),我也知道我应该首先使用new。 这是一个虚构的例子。 我在调试一大段代码时遇到了这个问题,我(目前)没有兴趣通过并用新的替换所有 malloc。
我只是想了解引擎盖下(基本上是对 bt 的解释)为什么分配 seg 出错。 我在想会调用对象 *my_str 的字符串复制赋值运算符,一切都应该解决。 但根据结果,我想不会。 任何见解将不胜感激。
谢谢艾哈迈德。
my_str = (string *) malloc(sizeof(*my_str));
这会为堆上的string
分配空间(而不是在C++免费存储区)。
它不做的是初始化内存。
因此,虽然我们现在有足够的空间来string
,但我们没有string
。
您的修复
my_str = new(my_str) string(name);
// Should cast the pointer-argument to `void*` before giving it to `new`.
// Otherwise, some other custom overload of `operator new` might match better.
使用 placement-new-expression 调用构造函数,并建立对象不变量(从而开始string
-objects 生存期)。
顺便说一句:constexpr void* operator new(size_t, void*)
被定义为只返回它的第二个参数,所以只有新表达式的第二部分,ctor-call,有任何影响。
如果您希望my_str指向与名称相同的数据,那么您想要的是
my_str = &name;
而且不需要马洛克。如果要复制它,请使用strcpy(在C中)或您显示为C++修复的行。
现在,您正在尝试将my_str指向的数据设置为字符串对象(分配指向取消引用值的指针)。
新表达式(如std::string* myString = new myString("hello"));
)执行两个步骤。首先,它为对象分配内存,然后调用构造函数来初始化对象。 当您使用 malloc 分配内存时,您拥有对象本身的内存,但它不会以任何方式初始化......只是任何任意的记忆恰好在那里。
在std::string
的情况下,实际的字符串数据是单独分配的。 当您分配给对象时,它将尝试将数据复制到对象内数据指针中的任何位置,这可能不是您的。
通过调用放置 new,您将调用构造函数来初始化已单独分配其内存的对象。
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- Seg Fault Issue C++ (file IO / getline)
- 空基优化子对象的地址
- 将对象数组的引用传递给函数
- 你能重载对象变量名本身返回的内容吗
- C++使用整数的压缩数组初始化对象
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 将对象移动到std::shared_ptr
- 代理对象的常量正确性
- 提升 ASIO 无法识别计时器对象
- 将Ref对象作为类成员
- 将包含C样式数组的对象初始化为成员变量(C++)
- 如何返回一个类的两个对象相加的结果
- 垫子对象数组太大会导致 Seg 错误
- 当有1个以上的对象时,动态字符串类断裂与SEG故障
- 使用全局对象静态成员时出现seg错误
- 将 python 对象传递到用 Cython 包装的类时出现 Seg 错误
- 将取消引用的对象分配给对象会导致 seg 错误