2

これはかなり基本的な質問であり、答えを知っていると確信していますが、間違っていることの結果はセグメンテーション違反であるため、質問する必要があると考えています。私はかなり長い間、次の方法で演算子を使用strlen()してきnew char[]ましたが、赤い旗を投げたものに気づきました。

void genericCopy(char *somestring, char *someOtherString) {
    someOtherString = new char[strlen(somestring)];
    strcpy(someOtherString,somestring);
}

私の質問は、文字列がnullで終了する必要があるため、これを次のように行う必要があるかどうかです。

void genericCopy(char *somestring, char *someOtherString) {
    someOtherString = new char[strlen(somestring)+1];
    strcpy(someOtherString,somestring);
    someOtherString[strlen(someOtherString)] = '\0';
}

これまでのところ、最初の方法で問題が発生したことはありませんが、それは私がそれを正しく行っているという意味ではありません. によって返される長さstrlen()は、null ターミネータを除いた文字列内の文字数であるため、new は '/0' のスペースを予約していません... 少なくともそうではないと思います。

4

2 に答える 2

3

まず第一に、あなたはあなたのこの関数を書くのは無意味であることを知っておくべきです、ただ使うだけstrdupです(あなたのシステムで利用可能な場合)。

ただし、はい、を格納するために追加のバイトが必要な\0ので、常に。のようなことをしてくださいnew char[strlen(somestring)+1];\0ただし、手動で;を追加する必要はありません。strcpyすでにこれを行います。

Valgrindのようなものを使用して、コード内のこのバグや同様のバグを発見する必要があります。

ただし、コードには追加の問題があります。あなたのコードは常にリークしsomeOtherStringます; 呼び出し元の場所には戻されません。メソッドを次のように変更する必要があります。

char *genericCopy(char *something) {
    char *copy = new char[strlen(somestring)+1];
    strcpy(copy,somestring);
    return copy;
}

次に、次のようにコピーを取得します。

copy = genericCopy(something);

または、メソッドを次のようなものに変更する必要があります。

void genericCopy(char *something, char **copy) {
    *copy = new char[strlen(somestring)+1];
    strcpy(*copy,somestring);
}

そしてそれを次のように呼びます:

genericCopy(something, &copy);

C ++を使用する場合は、メソッドのプロトタイプを次のように変更することもできます。

void genericCopy(char* somestring, char*& someOtherString)

そしてそれを次のように呼びます:

genericCopy(something, copy);

次にsomeOtherString、参照として渡され、それに割り当てた新しい値がメソッドの外部に伝播されます。

于 2012-07-07T05:00:28.500 に答える
1

はい、あなたの疑惑は正しいです。追加の文字を割り当て、コピーされた文字列がnullで終了していることを確認する必要があります。(strcpy()自体がこれを行いますが、誰かがstrncpy()に切り替えるようにアドバイスした場合、間違いなく(より安全です!)コピーすることが保証されていないため、特に注意する必要があります。 '/ 0'。)

ただし、すでにC ++を使用している場合は、std::stringの使用に切り替えることをお勧めします。多くの場合、文字配列を操作するための、より簡単でエラーが発生しにくい方法です。

ただし、対処する必要のあるさらなる問題があります。新しい文字配列をsomeOtherStringのCOPYに割り当てています。いくつかの変更を加える必要があります。

void genericCopy(char *somestring, char **someOtherString) {
    *someOtherString = new char[strlen(somestring)+1];
    strcpy(*someOtherString,somestring);
    (*someOtherString)[strlen(somestring)] = '\0';
}

このようにして、関数呼び出しの外部で新しい文字バッファーを取り戻すことができます。

于 2012-07-07T05:01:44.863 に答える