gpt4 book ai didi

c++ - 将 std::string 数据的深层拷贝存储到 std::vector

转载 作者:行者123 更新时间:2023-11-28 02:40:50 24 4
gpt4 key购买 nike

我一定是疯了,但我正在按照 Convert std::string to const char* or char* 中的示例进行操作我得到了很多 Invalid read of size 1在 valgrind 中。我基本上是在尝试拆分以空格分隔的字符串并将它们存储到 std::vector<const char*> 中.我知道这是因为从 c_str() 返回的指针随时可能失效,您必须执行复制才能安全地使用数据。但似乎我必须遗漏一些东西,因为 valgrind 正在提示。至少,我要复制最佳答案并执行以下操作:

#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: _IO_file_xsputn@@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: _IO_file_xsputn@@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==

我怀疑这个解决方案不起作用,因为 vector 中的数据在删除后指向垃圾。我也试过 args.push_back(std::move(writable)) .什么是解决方法?

最佳答案

这个例子说“不要忘记释放字符串在使用它之后”。您在将地址插入 vector 后立即删除内存。当您稍后尝试访问相同的地址时,这会导致代码非常损坏。

如果不考虑整个方法的优点(以及为什么要这样做),直接解决问题的方法是仅在完成后调用 delete使用 vector 中的地址。

请注意,您需要遍历 vector 并在 vector 中的每个地址上调用 delete

关于c++ - 将 std::string 数据的深层拷贝存储到 std::vector,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26052073/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com