我使用过此代码。这里从4开始的位置存在一个字符串,字符串的长度为14.所有这些计算都在此代码之前完成。我正在粘贴包含代码的错误的小片段。
void *data = malloc(4096);
int len = 14;
int fileptr = 4;
string str;
cout<<len<<endl;
cout<<fileptr<<endl;
memcpy(&str, (char *)data+fileptr, len);
cout<<len<<endl;
cout<<fileptr<<endl;
我得到的输出是:
14
4
4012176
2009288233
这里我正在从内存中读取字符串“System Catalog”。它正确显示字符串。但是在使用memcpy()函数后,fileptr和len的值突然发生了变化。
答案 0 :(得分:7)
string
与char*
不同。 string
是一个对象。所以你不能只是memcpy()
数据。所以这段代码的行为是未定义的。
在您的情况下,您将14字节的垃圾数据复制到str
并破坏堆栈。
结果是您使用len
中的垃圾覆盖fileptr
和malloc()
。
我不确定你要做什么,但是如果你想创建一个字符串,你应该这样做:
string str = "System Catalog";
答案 1 :(得分:3)
字符串是一个对象,不仅仅是一个字节序列。你不能只是从原始记忆中memcpy
过来。
我的猜测是,在你的代码中,str
变量在堆栈内存中的其他变量之前被分配,并且在它上面记忆你要覆盖它们。
请注意,您的短语“它正确显示字符串”会产生对C ++的常见误解。
当你在C ++中做坏事(例如在对象上写字节)时,你应该期待最糟糕的行为。然而,最糟糕的可能行为不是丑陋的结果,崩溃或运行时错误......但似乎可以工作,但将来会产生不良后果。
答案 2 :(得分:1)
您希望将这个 char指针中的这些字符分配到std::string
中,因此您应该查看字符串对象为此提供的功能而不是用memcpy()
击中头部。正如其他人所说,memcpy()
用于低级C风格代码,而不是用于与C ++对象交互。
特别是,您应该研究std::string
提供的assignment methods,其中一个完全符合您的要求 - 这不是巧合。
答案 3 :(得分:0)
如果由于某种原因你实际上必须使用memcpy,你可以获得要复制的字符串的内部地址(假设字符串足够大以包含你想要复制的信息)
static_cast < char * >(&(str[0]));
但这非常糟糕。如果你使用它,我很确定你的代码中会发生更多疯狂的事情: - )
答案 4 :(得分:0)
string
是一个对象 - 请查阅它的语义。你为什么这样做,你想要实现什么目标?