0
void pushSynonyms (string synline,  char  matrizSinonimos [1024][1024]){


             stringstream synstream(synline);

             vector<int> synsAux;


             int num;

             while (synstream >> num) {synsAux.push_back(num);}


             int index=0;
             while (index<(synsAux.size()-1)){

                   int primerSinonimo=synsAux[index];
                   int segundoSinonimo=synsAux[++index];
                   matrizSinonimos[primerSinonimo][segundoSinonimo]='S';
                   matrizSinonimos [segundoSinonimo][primerSinonimo]='S';

                   }

           } 

そしてコール..

char matrizSinonimos[1024][1024];
     pushSynonyms("1 7", matrizSinonimos)

私にとってはmatrizSinonimos参照渡しが重要です。

編集: から & を取り除きました&matrizSinonimos

編集:実行時エラーは次のとおりです。

An unhandled win32 exception occurred in program.exe [2488]![alt text][1]
4

6 に答える 6

5

どうしたの

そこにあるコード-バグが見つかりません。私が見つけた唯一の問題は、番号をまったく指定しないと、この部分が害を及ぼすことです。

(synsAux.size()-1)

0u から 1 を引きます。size()符号なし整数型を返すため、ラップアラウンドします。2^16 か 2^32 くらいの非常に大きな値になります。while 条件全体を次のように変更する必要があります。

while ((index+1) < synsAux.size())

呼び出し側のバグを探すことができます。多くの場合、その前にバッファ オーバーフローやヒープの破損が発生し、その結果、プログラムの後半でプログラムがクラッシュします。

その中の引数とパラメータのもの

配列とそれがどのように渡されるかについては、大丈夫だと思います。ただし、配列を値で渡します。ご存知かもしれませんが、繰り返します。この配列の最初の要素へのポインターを実際に渡します。

char matrizSinonimos[1024][1024];

2 次元配列は、実際には配列の配列です。その配列の最初の要素は配列であり、それへのポインターは配列へのポインターです。その場合は、

char (*)[1024]

パラメータリストで配列の配列を受け入れると言いましたが、コンパイラはいつものようにそれを調整し、そのような配列の最初の要素へのポインタにします。したがって、実際には、コンパイラによる引数の型の調整が行われた後、関数にはプロトタイプがあります。

void pushSynonyms (string synline,  char (*matrizSinonimos)[1024]);

よく提案されますが、呼び出された関数は、正しいオフセットでサブディメンションを正しくアドレス指定するために、内側のディメンションのサイズを必要とするため、その配列を として渡すことはできません。char**呼び出された関数で achar**を操作し、 のようなものを書くとmatrizSinonimos[0][1]、その配列の最初の sizeof(char**) 文字をポインターとして解釈しようとし、ランダムなメモリ位置を逆参照しようとし、次にそれを 2 番目に実行します。その間にクラッシュしなかった場合。そうしないでください。また、その配列の外側の次元にどのサイズを書き込んだかは関係ありません。それは合理化されました。さて、参照によって配列を渡すことはあまり重要ではありません。ただし、必要に応じて、すべてを次のように変更する必要があります

void pushSynonyms (string synline,  char (&matrizSinonimos)[1024][1024]);

参照渡しでは、最初の要素へのポインターは渡されません。すべての次元のすべてのサイズが保持され、値ではなく配列オブジェクト自体が渡されます。

于 2009-01-22T19:20:02.770 に答える
4

配列はポインタとして渡されます - それらへの参照渡しを行う必要はありません。関数を次のように宣言した場合:

void pushSynonyms(string synline, char matrizSinonimos[][1024]);

配列への変更は保持されます。配列が値渡しされることはありません。

于 2009-01-22T16:51:52.320 に答える
3

例外はおそらく0xC00000FD、またはスタックオーバーフローです!

問題は、スタック上に1 MBのアレイを作成していることです。これは、おそらく大きすぎます。

于 2009-01-22T18:55:23.383 に答える
0

次のように宣言してみてください。

void pushSynonyms (const string & synline,  char  *matrizSinonimos[1024] )

それがあなたのやりたいことになると信じています。他の人が言ったように、スタックに1MBのアレイを作成します。また、synline を からstringに変更するとconst string &、完全な文字列のコピーをスタックにプッシュする必要がなくなります。

また、ある種のクラスを使用して、matrizSinonimos をカプセル化します。何かのようなもの:

class ms
{
    char m_martix[1024][1024];
    public:
    pushSynonyms( const string & synline );
}

その場合、それを渡す必要はまったくありません。

于 2009-01-22T19:23:44.917 に答える
0

上記のコードの何が問題なのか途方に暮れていますが、配列構文が機能しない場合は、いつでもこれを実行できます。

void pushSynonyms (string synline,  char  *matrizSinonimos, int rowsize, int colsize )
{
   // the code below is equivalent to 
   // char c = matrizSinonimos[a][b];
   char c = matrizSinonimos( a*rowsize + b );
   // you could also Assert( a < rowsize && b < colsize );
}

pushSynonyms( "1 7", matrizSinonimos, 1024, 1024 );

コンパイル時にわかっている場合は、rowsize と colsize を #define SYNONYM_ARRAY_DIMENSION 1024 に置き換えることもできます。これにより、乗算ステップが高速になります。

于 2009-01-22T19:44:48.697 に答える
0

(編集 1 ) 実際の質問に答えるのを忘れていました。そうですね: 正しい方法で配列を渡すようにコードを修正した後 (不適切な間接参照がなくなりました)、入力を正しくチェックしなかった可能性が最も高いようです。ストリームから読み取り、ベクトルに保存しますが、取得したすべての数値が実際に正しい範囲内にあるかどうかを確認していません。(編集終了 1 )

最初:生の配列を使用することは、実際に必要なものではない場合があります。std::vector、またはがありますboost::array。後者は、raw-array のようなコンパイル時の固定サイズの配列ですが、C++ コレクションの型定義とメソッドを提供します。これは、一般的な (つまり、テンプレート化された) コードに実用的です。

また、これらのクラスを使用すると、型安全性、参照渡し、値渡し、またはポインターの受け渡しに関する混乱が少なくなる場合があります。

2 番目: 配列はポインターとして渡され、ポインター自体は値によって渡されます。

3 番目: このような大きなオブジェクトをヒープに割り当てる必要があります。このような場合、ヒープ割り当てのオーバーヘッドは重要ではなく、スタック領域が不足する可能性が低くなります。

第四

void someFunction(int array[10][10]);

本当に:

(編集 2 ) コメントのおかげで:

void someFunction(int** 配列);

void someFunction(int (*array)[10]);

うまくいけば、私は他の場所で失敗しませんでした....(編集終了2

10x10 配列になる型情報が失われます。おそらく意図したことを理解するには、次のように書く必要があります。

void someFunction(int (&array)[10][10]);

このようにして、コンパイラは呼び出し側で配列が実際に 10x10 配列であることを確認できます。次に、次のように関数を呼び出すことができます。

int main() {
  int array[10][10] = { 0 };
  someFunction(array);
  return 0;
}
于 2009-01-22T18:46:02.183 に答える