6

さて、の質問は明確に答えられましたが、私は別の問題を発見しました。

私がやったら:

char *test(int ran){ 
    char *ret = new char[ran]; 
    // process... 
    return ret; 
} 

そしてそれを実行します:

for(int i = 0; i < 100000000; i++){ 
   string str = test(rand()%10000000+10000000); 
   // process... 

   // no need to delete str anymore? string destructor does it for me here?
} 

したがって、char *をstringに変換した後、削除について心配する必要はありませんか?

編集:答えたように、私はdelete[]それぞれnew[]の呼び出しをしなければなりません、しかし私の場合、ポインタが失われたのでそれは不可能です、それで問題は:どうやってcharをstringに正しく変換するのですか?

4

5 に答える 5

9

ここでは、をに変換するのではなくをにコピーします。char*[std::]stringchar*[std::]string

経験則として、すべてに対して。newが必要deleteです。

この場合、delete完了時にポインタとそのコピーを保存する必要があります。

char* temp = test(rand()%10000000+10000000);
string str = temp;
delete[] temp;
于 2010-06-03T13:44:35.503 に答える
3

achar*を std::string に渡すと、割り当てられたメモリの所有権が譲渡されるという印象を受けているようです。実際には、コピーを作成するだけです。

これを解決する最も簡単な方法は、関数全体で std::string を使用し、それを直接返すことです。

std::string test(int ran){ 
    std::string ret;
    ret.resize(ran - 1);  // If accessing by individual character, or not if using the entire string at once.
    // process... (omit adding the null terminator)
    return ret; 
} 
于 2010-06-03T13:53:22.627 に答える
2

はい、そうです。

linux / os xを使用している場合は、メモリの問題に役立つvalgrindのようなものを調べてください

stringテスト関数を変更して、の代わりにを返すようにすることchar *ができます。これにより、テスト関数で行うことができdelete [] retます。

または、テストで文字列を使用するだけで、新規/削除について心配する必要はありません。

于 2010-06-03T13:43:38.683 に答える
2

次のようなことをする必要があります:

for(int i = 0; i < 100000000; i++){ 
   int length = rand()%10000000+10000000;
   char* tmp = test(length); 
   string str(tmp);
   delete[length] tmp;
}

これにより、割り当てられた文字配列が適切に削除されます。

ところで、この方法で (つまり、関数内で) 文字列を作成する場合は、常に文字列をゼロで終了する必要がありますtest。そうしないと、一部の関数が簡単に「混乱」して、文字列の背後にあるデータをその一部として扱う可能性があります。アプリケーションがクラッシュし、最悪の場合、サイレント バッファ オーバーフローが発生して、後で未定義の動作が発生します。これは、デバッグの究極の悪夢です... ;)

于 2010-06-04T00:20:38.943 に答える
2

そうしないdeletenewメモリリークが発生します。ポインターを破棄していることを示した場合、関数を a を返すままにしておく必要がある場合は、 toのコピーを保持できるようchar*に を作成するために 2 行を使用する必要があります。std::stringchar*delete

より良い解決策は、関数を書き直してaを直接test()返すことです。std::string

于 2010-06-03T13:58:13.507 に答える