2012-03-28 4 views
1

ある文字列を別の文字列に追加しようとしている。 2つのグローバル文字列変数を宣言します -Valgrindはstring.append(string)に文句を言う。

string grid_filename = "grids/"; 
string rest; 

次に、コマンドライン引数を取得する関数があります。ユーザーがコマンドライン引数にファイル名を入力すると、そのファイルはrestに格納され、次にrestがgrid_filenameに追加されます。

==5602== Address 0x45fdc30 is 0 bytes after a block of size 32 alloc'd 
==5602== at 0x402641D: operator new(unsigned int) (vg_replace_malloc.c:255) 
==5602== by 0x43039F7: std::string::_Rep::_S_create(unsigned int, unsigned int,  std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.14) 
==5602== by 0x4304C77: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned int) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.14) 
==5602== by 0x4304DA6: std::string::reserve(unsigned int) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.14) 
==5602== by 0x43053E9: std::string::append(std::string const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.14) 
==5602== by 0x804D5AE: get_command_line_args(int, char**) (main.cpp:74) 
==5602== by 0x804F138: main (main.cpp:244) 

は、私は、文字列の2つのアドレスをプリントアウトし、それらのいずれも1つのvalgrindのは0バイトであると言っている一致 - 私は私のコードを実行するたびに

else if(strcmp(temp.substr(0,16).c_str(), "--grid-filename=") == 0) { 
    rest = temp.substr(16,strlen(temp.c_str())-16); 
    grid_filename.append(rest); //line 74! 
} 

は今、valgrindのは私に、このエラーが発生します。私はここで何が欠けていますか?

これは、grid_filenameをtcp接続で文字列を送信する別の関数に渡すため、これが私の2番目のエラーにつながると思います。 Valgrindは私に教えてくれます

==5660== Syscall param socketcall.send(msg) points to unaddressable byte(s) 
==5660== at 0x404A9B1: send (socket.S:64) 
==5660== by 0x804F7C8: main (main.cpp:364) 

問題は何ですか?どんな助けもありがとう。必要に応じてコードについて詳しく説明します。

+1

Goodness! ...... –

+0

最初に表示されるエラーメッセージは完全ではありません。実際のエラーメッセージは、貼り付けたテキストのすぐ上になければなりません。つまり、0x45fdc30への読み書きについてです。次に、valgrindは貼り付けたメッセージを表示します。このメッセージには、そのアドレスに関する情報が表示されます。 – wolfgang

+0

私が投稿した2番目のエラーメッセージは、最初に投稿したものの上に表示されます。彼らは分かれていると分かりましたので、私は別々に書きました。メッセージ全体は、 "Syscall param socketcall.send(msg)がアドレスできないバイトを指している"で始まり、 "アドレス0x45fdc30はサイズ32のalloc'd"ブロックの後に0バイトです。 – Sterling

答えて

0

最初のエラーについて:valgrindに誤検出がありました。 documentation彼らはあなたのコードを指していません(そして、あなたは、彼らが実際に問題が発生していないことを確認している)場合は特に、

0

をこれらを抑制するための注意事項を確認します。これは、応答はありませんが、これはコードレビューサイトではありません...実際に私はこれを見て離れて歩くことはできません。

まず、実際にツールボックスに役立ついくつかの機能:

// Some free functions (because there are too many string types) 
inline char const* c_str(std::string const& s) { return s.c_str(); } 
inline size_t size(std::string const& s) { return s.size(); } 

inline char const* c_str(char const* s) { return s; } 
inline size_t size(char const* s) { return std::strlen(s); } 

template <size_t N> 
char const* c_str(char const (&s)[N]) { return s; } 
template <size_t N> 
size_t size(char const (&s)[N]) { return N - 1; } 

// A helper function (lowest common denominator) 
inline bool beginsWith(char const* big, size_t const bigSize, 
         char const* small, size_t const smallSize) 
{ 
    if (bigSize < smallSize) { return false; } 
    return std::memcmp(big, small, smallSize) == 0; 
} 

// The actual function, doing the adaptation from the various forms of string 
template <typename T, typename U> 
bool beginsWith(T& big, U& small) { 
    return beginsWith(c_str(big), size(big), c_str(small), size(small)); 
} 

// same with endsWith 

をそして、あなたは非常に効率的に(余分なメモリ割り当て)コードを書き換えることができ、あまりにも多くの可読性を持つ:

static std::string const GridFilenameOpt = "--grid-filename="; 

// ... 
else if (beginsWith(temp, GridFilenameOpt)) { 
    grid_filename.append(temp, GridFilenameOpt.size(), std::string::npos); 
} 

あなたはエラーを生成するコードを表示していないので、実際の質問にはあまり役に立ちません。

+0

'startsWith'が必要な場合は、' bool startsWith(string const&a、string const&b){return a。(0、b.length()、b);} '? –

+0

@ JerryCoffin:私は、この比較を行うためにちょうど偽の一時的な 'string'を作成する考えが嫌いです。問題は、C++( 'std :: string'と' char const * 'と' 'char const(&)[N]')の3つの文字列型のすべての組み合わせを列挙するのは退屈なので、 (私は、この統一のために 'llvm :: StringRef'に似たクラスを使用しています)。 –

+0

上記の関数は、比較のために新しい文字列を作成すべきではありません。比較の開始点と長さを指定できる 'compare'メンバ関数を使用しているだけです。これは 'string'のためだけに書かれていますが、一般的に' basic_string'のために一般化するのは簡単です。同時に、 'memcmp'を使用すること自体がかなり制限されています... –

関連する問題