3

以下のコードを実行しましたが、完全に機能します。ポインタに関するものなので、確認したいだけです。文字列にchar*を割り当てるとコピーが作成されると確信していますが、char *を削除しても、stringvarは値を保持します。

    #include <stdio.h>
    #include <string.h>
    #include <string>
    #include <iostream>

    int main()
    {
        std::string testStr = "whats up ...";
        int strlen = testStr.length();
        char* newCharP = new char[strlen+1];
        memset(newCharP,'\0',strlen+1);
        memcpy(newCharP,testStr.c_str(),strlen);


        std::cout << "  :11111111   :   " << newCharP << "\n";
        std::string newStr = newCharP ;

        std::cout << "  2222222 : " << newStr << "\n";
        delete[] newCharP;
        newCharP = NULL;

        std::cout << "  3333333 : " << newStr << "\n";
    }

会社のプロジェクトでいくつかのコードを変更しているだけで、char*はC++の関数間で渡されます。char *ポインタが文字列にコピーされましたが、関数の最後でchar*が削除されています。これについての具体的な理由は見つかりませんでした。したがって、文字列にコピーされるとすぐに、char*を削除するだけです。これは問題になりますか...?

PS:Codereviewでこの質問をすでにしましたが、SOに移動するよう提案されました。だから私はそこに近いことを示し、ここに質問を投稿しました。

4

3 に答える 3

10

いいえ、std::stringの内容をコピーするためchar*、不要になったときに自由に削除できます。

于 2013-03-10T13:24:41.027 に答える
6

newCharnullで終了する文字列を指し、それ自体がnullでない限り、問題はありません。

std::stringからの暗黙的な構築を可能にするコンストラクターがありconst char*ます。入力で表される文字列のコピーを作成するため、文字列自体のデータストレージにコピーする文字数を知る方法が他にないため、はnullで終了する文字列であるとconst char *想定して機能します。char*さらに、NULLポインタは実際には標準では許可されていません。

于 2013-03-10T13:25:26.320 に答える
1

コードは問題ありません。ここのコンストラクターを見ると、std::basic_string ここstd::stringに 2 つの興味深いコンストラクターがあると推測できます。

(4) string(char const*,
           size_type count,
           Allocator const& alloc = Allocator() );

(5) string(char const* s,
           Allocator const& alloc = Allocator() );

どちらもコピーを実行し、1 つ目は正確にcount文字を読み取り、2 つ目は NUL 文字に遭遇するまで読み取ります。


そうは言っても、ここでは動的割り当てを使用しないことを積極的にお勧めします。一時的なバッファで遊ぶ場合は、std::vector代わりに使用することを検討してください。

#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>

int main()
{
    std::string testStr = "whats up ...";
    unsigned strlen = testStr.length();

    std::vector<char> buffer(strlen+1);

    memset(&buffer[0],'\0',strlen+1);
    memcpy(&buffer[0], testStr.c_str(), strlen);

    std::cout << "  :11111111   :   " << &buffer[0] << "\n";

    std::string newStr(&buffer[0]);

    std::cout << "  2222222 : " << newStr << "\n";

    buffer.clear();

    std::cout << "  3333333 : " << newStr << "\n";
}

注: と の両方vectorstring範囲コンストラクターがあり、一連のイテレーターからそれらを構築します。混乱を避けるために意図的に使用を控え、圧倒されることはありません。memcpyただし、バッファオーバーフローの呼び出しとリスクを回避するためにそれらを使用できた可能性があることを知っておいてください.

于 2013-03-10T14:09:07.237 に答える