5

次の問題があります。Cライブラリをラップアラウンドする必要があるC++プログラムを作成しているため、ライブラリを操作するときは、すべての操作ではchar*なく、常に使用する必要がstd::stringあります。できるだけ作業を避けるためにchar*、たとえば次のように、文字列ストリームを使用してフォーマットを行います。

#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)

私は何が間違っているのですか?

4

1 に答える 1

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

str()は文字列オブジェクトを返します。c_strを使用してその内部データへのポインタを取得し、行の終わりで文字列オブジェクトが削除されます。ただし、削除された内部文字列へのポインタはまだあります。

あなたはこのようにする必要があります-

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

文字列が削除されないようにします。

于 2012-07-18T08:45:13.733 に答える