我一定要疯了,但我在Convert std::string to const char* or char*的例子之后,我在valgrind中得到了很多Invalid read of size 1
。我基本上试图分割空白分隔的字符串,并将它们存储到std::vector<const char*>
。我知道,因为从c_str()
返回的指针可能随时失效,您必须执行一个副本才能安全地使用数据。但是,自从valgrind抱怨之后,我似乎一定会失去一些东西。在绝对最低,我复制了顶部的答案,这样做:将std :: string数据的深拷贝存储到std :: vector中
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int main()
{
std::vector<const char*> args;
std::string str = "hey";
char * writable = new char[str.size() + 1];
std::copy(str.begin(), str.end(), writable);
writable[str.size()] = '\0'; // don't forget the terminating 0
args.push_back(writable);
delete[] writable;
for (size_t i = 0; i < args.size(); ++i)
cout << args[i] << "\n";
return 0;
}
下面的输出,这导致从Valgrind的:
==5297== Invalid read of size 1
==5297== at 0x4C2BFC2: __GI_strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5297== by 0x400CFF: main (in /tmp/1411705143.17426/a.out)
==5297== Address 0x5c2a0a0 is 0 bytes inside a block of size 4 free'd
==5297== at 0x4C2A09C: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5297== by 0x400CD9: main (in /tmp/1411705143.17426/a.out)
==5297==
==5297== Invalid read of size 1
==5297== at 0x4C2BFD4: __GI_strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5297== by 0x400CFF: main (in /tmp/1411705143.17426/a.out)
==5297== Address 0x5c2a0a1 is 1 bytes inside a block of size 4 free'd
==5297== at 0x4C2A09C: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5297== by 0x400CD9: main (in /tmp/1411705143.17426/a.out)
==5297==
==5297== Invalid read of size 1
==5297== at 0x58E6DB8: _IO_default_xsputn (genops.c:480)
==5297== by 0x58E4D19: [email protected]@GLIBC_2.2.5 (fileops.c:1393)
==5297== by 0x58DA98C: fwrite (iofwrite.c:45)
==5297== by 0x4EC8A35: std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) (streambuf:451)
==5297== by 0x400D0F: main (in /tmp/1411705143.17426/a.out)
==5297== Address 0x5c2a0a0 is 0 bytes inside a block of size 4 free'd
==5297== at 0x4C2A09C: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5297== by 0x400CD9: main (in /tmp/1411705143.17426/a.out)
==5297==
==5297== Invalid read of size 1
==5297== at 0x58E6DC7: _IO_default_xsputn (genops.c:479)
==5297== by 0x58E4D19: [email protected]@GLIBC_2.2.5 (fileops.c:1393)
==5297== by 0x58DA98C: fwrite (iofwrite.c:45)
==5297== by 0x4EC8A35: std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) (streambuf:451)
==5297== by 0x400D0F: main (in /tmp/1411705143.17426/a.out)
==5297== Address 0x5c2a0a2 is 2 bytes inside a block of size 4 free'd
==5297== at 0x4C2A09C: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5297== by 0x400CD9: main (in /tmp/1411705143.17426/a.out)
==5297==
我怀疑,这种解决方案并不因为工作删除后,矢量内的数据指向垃圾。我也试过args.push_back(std::move(writable))
。什么是解决方法?
为什么不直接存储'std :: string'?为什么要让自己头疼存储'char'数组副本? – Brandon 2014-09-26 04:36:58