-2

push_back を使用したときのベクター コンテナーの動作をシミュレートしようとしています。ポインターの配列を作成しました。各要素の長さは異なる場合があるため、新しい要素が格納されるたびに再割り当てする必要があります。

   void *reallocf(void *p, size_t s)
{
    void *tmp = realloc(p, s);
    if(tmp) return tmp;
    free(p);
    return NULL;
}
int main(){
   int rows = 9000;
   int cols = 23000; 
   int *matrix = (int*)malloc(sizeof(int)*rows*cols);

   //counter of elements
   int *nums = new int [rows];
   memset(num, 0, sizeof(int)*rows)

    /* populate matrix*/
            ....
   int **Xcc = new int *[rows];


  for(i = 0; i < rows; i++){
      for(k = 0; k < cols; k++){
          if(matrix[i*cols +k] == 0){
             Xcc[i] = (int*) reallocf(Xcc[i], sizeof(int)*(num[i]+1));
             Xcc[i][num[i]] = k;
             num[i]++;
          }
       }
   }

}

基本的に私がやっていることは、0 である要素の位置を格納することです。そのため、配列Xcc[i]は必要になるたびに 1 要素ずつ増加します。新しい長さは、以前の 1 に 1 を加えたものになり、保存されます。

どうやら私には問題ないようですが、それは私が得ているものに依存し、segmentation faultsさまざまな角度からそれを見た後、私は現在立ち往生しています。どんな助けでも、アイデアや提案は素晴らしいでしょう。

4

3 に答える 3

3

おそらく問題はこれです:あなたがするとき

int **Xcc = new int *[rows];

ジェネリック i の Xcc[i] が初期化されていない場合、realloc() の呼び出しが機能する場合 (Xcc[i] が null の場合) と機能しない場合 (segfault) があります。

次のものがありません:

memset(Xcc, 0, sizeof(int*) * rows);
于 2012-09-14T16:37:22.650 に答える
2

freeによって再割り当てされたポインターを明示的に指定する必要はありませんreallocrealloc渡されたポインタを解放します (そうでない場合NULL)。

したがって、関数から削除free(p);しますreallocf()

そして、@ Joachim Pileborg が指摘したように、 で割り当てられたメモリを再割り当てすることはできませんnew。に変更newmallocます。

于 2012-09-14T16:12:01.787 に答える
1
 if(matrix[i*cols +k] == 0){
         Xcc[i] = (int*) reallocf(Xcc[i], sizeof(int)*(num[i]+1));
         Xcc[i][num[i]] = k; // bad access here

kまず、またはのいくつかの値に対して有効な条件に基づいて、メモリを再割り当てしていますj。第二に、再割り当てが失敗すると、戻って次のようにしnullてメモリへのアクセスを試みます。0

  Xcc[i][num[i]] = k;

質問

  • マトリックスの役割は何ですか?
  • true のmatrix後に変更しないのはなぜですか。matrix[i*cols +k] == 0

備考

  • 1空きがない時まで増やさない!ある時点以降、挿入ごとに1つの再割り当てが必要になるため、ITは非常に非効率的です。

必要ありませんreallocf。realloc が失敗すると、元のメモリは変更されません。新しい項目にさらにスペースを割り当てることができない場合は、挿入メソッドを停止してエラーを返します。

于 2012-09-14T16:16:36.080 に答える