【发布时间】:2015-10-18 14:13:33
【问题描述】:
我编写了以下代码,它似乎可以与旧的 std::string 实现一起正常工作。但是使用 gcc 5.1,它会崩溃。
#include <string>
#include <iostream>
#include <cstring>
struct abc
{
public:
abc() {}
abc(const std::string& x)
: gullu(x)
{
}
std::string gullu;
};
int main()
{
abc *a = new abc("dhfghdf");
abc *b = new abc();
memcpy((void *)&b, (void *)&a, sizeof(abc));
std::cout << a->gullu.data() << std::endl;
std::cout << b->gullu.data();
return 0;
}
调试了一下,发现做memcpy后对象'a'的内容变成了垃圾。
a 的构造后,
(gdb) p *a $1 = {gullu = {静态 npos = 4294967295, _M_dataplus = {> = {<:new_allocator> = {}, }, _M_p = 0x804ea18 "dhfghdf"}, _M_string_length = 7, {_M_local_buf = "dhfghdf\000\000\000\000\000\000\000\000", _M_allocated_capacity = 1734764644}}}
b 构造后
(gdb) p *b $2 = {gullu = {静态 npos = 4294967295, _M_dataplus = {> = {<:new_allocator> = {}, }, _M_p = 0x804ea38 ""}, _M_string_length = 0, {_M_local_buf = '\000' , _M_allocated_capacity = 0}}}
memcpy 之后
(gdb) p *a $4 = {gullu = {静态 npos = 4294967295, _M_dataplus = {> = {<:new_allocator> = {}, }, _M_p = 0x666468 },_M_string_length = 2572404,{_M_local_buf = "t@'\000\030Ùÿ¿I\215\004\b\001\000\000", _M_allocated_capacity = 2572404}}}
(gdb) p *b $5 = {gullu = {静态 npos = 4294967295, _M_dataplus = {> = {<:new_allocator> = {}, }, _M_p = 0x804ea18 "dhfghdf"}, _M_string_length = 7, {_M_local_buf = "dhfghdf\000\000\000\000\000\000\000\000", _M_allocated_capacity = 1734764644}}}
我正在使用一个第三方库,它似乎在做一个 memcpy,它与以前的编译器一起工作,但由于这个问题而不能与 gcc 5.1 一起工作
有人可以帮我解决这个问题吗?
【问题讨论】:
-
你为什么要使用
memcpy()而不是拷贝构造函数呢?无论是哪个编译器版本,您一直称之为未定义的行为。 -
我正在使用一个第三方库,它似乎在做一个 memcpy,由于这个问题,它与以前的编译器一起工作,而不是与 gcc 5.1 一起工作
-
不要 memcpy std::string。您需要阅读浅拷贝的后果。无论如何,即使没问题,您也应该只复制指针的大小,因为这是您从
&a得到的。 -
GCC 5.1(C++11/C++14/C++17)对我来说不会崩溃。给出输出dhfghdf dhfghdf -
@Praveen:未定义的行为通常很难重现。