2012-07-18 28 views
5

私は以下の問題を抱えています:CライブラリをラップするC++プログラムを作成していますので、ライブラリとやりとりするときには常にstd::stringの代わりにchar*を使用する必要があります。stringstreamsでストルードするとvalgrindエラーが発生する

#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」を出力:できるだけchar*で作業を避けるために、私はこのような、たとえば、stringstreamsでフォーマットします。しかし、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) 

のエラーの多くを提供しますか?

答えて

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

str()は文字列オブジェクトを返します。 c_strを使用してその内部データへのポインタを取得し、その行の最後に文字列オブジェクトを削除します。しかし、あなたはまだ削除された内部文字列へのポインタを持っています。

あなたはこのようにそれを行う必要がある - 文字列が削除されないことを保証するために

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

+0

'char * y = strdup(str.str()。c_str());'と書いても問題ないでしょうか? –

+0

はい、それはうまくいくでしょう - そのメモリが削除される前に文字列をコピーし、後でポインタのコピーを保持しないようにしてください。 – jcoder

+3

@JonasWielickiはい。一時的な生涯は完全な表現の終わりまでです。 (私は実際にはこのような簡潔なものを好むでしょうが、意見は異なります。不要な中間変数をたくさん導入することは望ましくありませんが、式も複雑すぎることは望ましくありません。あなたが誰に依頼するか)。 –

関連する問題