c++ - 带有 stringstreams 的 strdup 导致 valgrind 错误

标签 c++ valgrind

我有以下问题:我正在编写一个必须环绕 C 库的 C++ 程序,所以当我与库交互时,我总是必须使用 char* 而不是 std::string 用于所有操作。为了尽可能避免使用 char*,我使用 stringstreams 进行格式化,例如:

#include <iostream>
#include <sstream>
#include <string.h>
#include <cstdlib>

using namespace std;

int main(int argc, char** argv)
{
  ostringstream str;

  str << argv[0] << "+" << "hello";

  const char *s = str.str().c_str();

  char *y = strdup(s);

  // this I would give to a library function

  cout << y << endl;

  free(y);

  return 0;
}

就输出而言,程序正确输出“./test+hello”。但是,valgrind 给了我很多类型的错误

==30350== Invalid read of size 1
==30350==    at 0x402B858: __GI_strlen (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==30350==    by 0x4213475: strdup (in /usr/lib/libc-2.16.so)
==30350==    by 0x41B2604: (below main) (in /usr/lib/libc-2.16.so)
==30350==  Address 0x4341274 is 12 bytes inside a block of size 25 free'd
==30350==    at 0x4029F8C: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==30350==    by 0x410387A: std::string::_Rep::_M_destroy(std::allocator<char> const&) (in /usr/lib/libstdc++.so.6.0.17)
==30350==    by 0x41B2604: (below main) (in /usr/lib/libc-2.16.so)

我做错了什么?

最佳答案

 const char *s = str.str().c_str();

str() 返回一个字符串对象。您使用 c_str 获得指向它的一些内部数据的指针,然后在该行的末尾删除字符串对象。但是您仍然有一个指向已删除的内部字符串的指针。

你需要这样做 -

std::string s = str.str();
const char* s = s.c_str()

确保字符串没有被删除。

关于c++ - 带有 stringstreams 的 strdup 导致 valgrind 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11537367/

相关文章:

c++ - 为什么要在 Linux 中挂载文件

c++ - 在不关闭套接字的情况下使用 Boost::ASIO 连续传输数据

c++ - 即使缺少函数定义,编译也会成功

我可以让 valgrind 忽略 glibc 库吗?

linux - 在 Valgrind/DrMemory 中记录程序状态然后恢复是否可行?

c++ - iostream 等效于 cstdio "%c"的格式化程序?

c++ - 我的程序只处理输入中的一行

c++ - Valgrind显示内存泄漏? ffff可能与相关吗?

c - 我遇到段错误,valgrind 通过 getline 显示此错误

条件跳转或移动取决于指向第一行代码的未初始化值