1

こんにちは、私の問題は説明が難しいので、ここにコード セクションを投稿し、例を挙げて問題を説明します。

このコードには大きな配列と小さな配列があり、大きな配列は小さな部分に分割され、小さな配列に格納され、小さな配列はそのコンテンツを画面に出力しています。
その後、小さな配列の割り当てられたメモリを解放し、大きな配列の次の部分で再度初期化します。

//this code is in a loop that runs until all of the big array has been copied
char* splitArray = new char[50];        
strncpy(splitArray, bigArray+startPoint, 50); //startPoint is calculated with every loop run, it marks the next point in the array for copying

//output of splitArray on the screen here

delete splitArray;
//repeat loop here

今私の問題は、出力された文字列の最後に毎回ランダムな記号があることです。例えば"some_characters_here...last_char_hereRANDOM_CHARS_HERE".

詳しく調べたところ、splitArray のサイズは実際には 50 ではなく、null ターミネータが 64 の 64 であることがわかりました。そのため、bigArray から splitArray にコピーすると、実際の文字列の後に 14 個のランダムな文字が残っています。もちろん、私はそれらを出力したくありません。

簡単な解決策は、手動で splitArray の null ターミネータを [50] に設定することですが、プログラムは再び配列の削除に失敗します。

これに対する解決策を見つけるのを手伝ってくれる人はいますか? できればいくつかのサンプルコードを使用してください、ありがとう。

4

5 に答える 5

0

この関数strncpyには、ソース文字列に 50 文字を超える文字が含まれている場合、宛先文字列が終了しないという欠点があります。それはあなたの場合のようです!

これが本当に C++ である場合は、std::string splitArray(bigArray+startPoint, 50).

于 2012-02-15T12:35:45.937 に答える
0

あなたのコードにはいくつかの問題があります。

  1. を使用して割り当てた場合は、 (ではなく)new []で解放する必要があります。delete []delete
  2. とにかく、なぜ freestore を使用しているのですか? 私が見ることができることから、ローカル配列を使用することもできます。
  3. 配列に 50 文字を格納する場合は、終端の null 文字に 51 文字が必要です。

あなたはいくつかのコードが欲しかった:

while(/* condition */)
{
    // your logic

    char splitArray[51];
    strncpy(splitArray, bigArray+startPoint, 50);
    splitArray[50] = '\0';

    // do stuff with splitArray
    // no delete
}
于 2012-02-15T12:39:55.287 に答える
0

NULL 文字で満たされていないメモリにメモリを割り当てる場合はsplitArray、明示的に行う必要があります。このため、文字列が適切に NULL で終了していません。これを行うchar* splitArray = new char[51]();には、割り当て時に NULL 文字で初期化することができます (最後に追加の NULL 文字を含めるために 51 文字を割り当てていることに注意してください)。. また、する必要があることにも注意してdelete[] splitArray;くださいdelete splitArray;

于 2012-02-15T12:28:15.170 に答える
0

設定しただけの場合、プログラムはどのように「アレイの削除に失敗しましたか」splitArray[49] = 0? splitArray[50] = 0長さ 50 の配列は 0 から 49 までのインデックスが付けられていることを忘れないでくださいsplitArray

于 2012-02-15T12:27:23.777 に答える
0

これを行うだけで十分です。

char* splitArray = new char[50 + 1];        
strncpy(splitArray, bigArray+startPoint, 50);
splitArray[50] = '\0';

とにかく、なぜあなたがこれをしているのか本当に疑問に思います。これはもっときれいです:

std::string split(bigArray+startPoint, 50);

コピーは引き続き行いますが、割り当て (解除) と終了を処理します。次のように、基になる文字ポインターを取得できます。

char const *s = split.c_str();

正しく nul で終了し、文字列オブジェクトと同じ寿命を持ちます (つまり、freeまたはdeleteそれを行う必要はありません)。


注意。元のコードは変更していませんが、魔法の整数リテラルを失うことも良い考えです。

于 2012-02-15T12:34:59.327 に答える