1

結論:みんな本当にありがとう!以下に投稿されたすべての回答は正しかった。最初のエラーは、NULL ターミネータの余地を残すのを忘れていたことです。Strcpy() は危険な関数です。なぜなら、私がそれを使用したとき、「文字列」の終わりがいつなのかわからなかったからです。そのため、strcpy() は多くのデータを取得し、戻りアドレスを上書きしました。

編集:プログラムからさらにコードを追加

解決済み: 正直なところ、私の最初の実装はくだらないものでした。配列の要素をスワップアウトしたいのに、なぜそのように swap を書いたのかさえわかりません。(当時、各要素には a char 配列しかありませんでした。そのため、古い実装で逃げることができました)。私はそれを次のように書き直しました:

void swap(ArrayElement list[], int index1, int index2) {
     ArrayElement temp;
     temp = list[index1];
     list[index1] = list[index2];
     list[index2] = temp;
}

次の関数の最後にあるセグメンテーション違反に問題があります。

struct ArrayElement {
    char data[SIZE_OF_ELEMENT];
    // Implemented this way so that I can expand to multiple values later on
}

//In main:
ArrayElement* list = new ArrayElement[NUM_OF_ELEMENTS];

void swap(ArrayElement list[], int index1, int index2) {
     char temp[SIZE_OF_ELEMENT];
     strcpy(temp, list[index2].data);
     strcpy(list[index2].data, list[index1].data);
     strcpy(list[index1].data, temp);
}

エラーは、関数の終了中かっこである 45 行目のセグメンテーション違反です。これは g++ を使用してコンパイルされました。gbd を使用してデバッグを試みたところ、中括弧に到達するまですべてが正しく機能しました。

必要に応じて、プログラムからさらにコードを提供できます。これはクラス用なので、すべてを投稿したくありません。

4

3 に答える 3

5

私の最善の推測では、文字列 atlist[index2].dataはより大きく、temp[]コピーすることで、スタックと戻りアドレスを上書きしました。

長さのテストを挿入してみてください。

#include <iostream>

...
int n = strlen(list[index2].data);
std::cerr << "len=" << n << ", SIZE_OF_ELEMENT=" << SIZE_OF_ELEMENT << std::endl;

n(list[index2].data) がより大きいかどうかを確認します。SIZE_OF_ELEMENT

于 2012-10-25T20:44:02.870 に答える
2

strcpy危険な機能です。入力文字列の長さがSIZE_OF_ELEMENT以上の場合、temp配列の末尾を超えて書き込みます。で固定サイズの配列を出力配列として使用する必要がある場合は、関数を使用する前に が機能するstrcpyことをテストする必要があります。strcpy

charさらに良いのは、配列の使用から に切り替えることstd::stringです。

于 2012-10-25T20:52:01.830 に答える
1

データはこのように定義されていchar data[SOME_CONSTANT]ますか? もしそうなら、SIZE_OF_ELEMENT が十分に大きいと確信していますか? NULL ターミネータも覚えていますよ

ArrayElement でデータがこのように定義さchar *data;れ、後で malloc で割り当てられた場合、index1 には index2のデータに対して十分な大きさのバッファがあり、その逆も同じであると確信していますか? 繰り返しますが、NULL ターミネータも覚えていますよ?

于 2012-10-25T20:54:38.000 に答える