2016-04-08 170 views
6

私は動的に作成された2D配列を持っています。C++で動的二次元配列を初期化するためにmemsetまたはfill_nを使用する方法

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

for (uint32_t i = 0; i < rows; i++) 
{ 
    abc[i] = new int[cols]; 
} 

私はいくつかの値(1と言う)で配列を埋めるためにしたいです。私は各項目をループしてやることができます。

しかし、より簡単な方法があります。私はthis postで述べたようにmemsetstd::fill_nを使用しようとしています。

std::fill_n(abc, rows * cols, 1); 
memset(abc, 1, rows * cols * sizeof(int)); 

memsetを使用すると、プログラムがクラッシュします。 fill_nを使用すると、コンパイルエラーが発生します。

invalid conversion from 'int' to 'int*' [-fpermissive] 

私はここで間違っていますか?

+0

が戻ってCに落とす選択肢かもしれません。 'int(* abc)[cols] = malloc(rows * sizeof(* abc)); memset(abc、1、rows * sizeof(* abc)); 'はC99以降は合法ですが、C++ではすぐには使用できません。 – cmaster

答えて

5

あなただけvectorを使用することができます:あなたが直接abcstd::fill_nまたはmemsetを使用することはできません

std::vector<std::vector<int>> abc(rows, std::vector<int>(cols, 1)); 

、それは単に動作しません。

​​

または私はあなたがstd::fill_nとの組み合わせでstd::generate_nを使用することができると思いますが、これは単にそうです:

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

for (uint32_t i = 0; i < rows; i++) 
{ 
    abc[i] = new int[cols]; 
    std::fill_n(abc[i], cols, 1); 
} 

または単一次元全体を作る:あなただけのサブアレイのいずれかで使用することができます混乱:

int **abc = new int*[rows]; 
std::generate_n(abc, rows, [cols]{ 
    int* row = new int[cols]; 
    std::fill_n(row, cols, 1); 
    return row; 
}); 
+1

@ NathanOliverありがとう! – Barry

3

私はここにあなたの主な問題は、あなたがint値の配列を持っていないということだと思います。あなたはintへのポインタの配列を持っています。

ここで達成しようとしていることを理解している場合は、おそらくint* abc = new int[rows * cols];で始まり、ここから作業する必要があります。

2

ちょうどあなたが既に持っているループ内で*を使用します。メモリが新しいint型の配列をマップする場所

for (uint32_t i = 0; i < rows; i++) 
{ 
    abc[i] = new int[cols]; 
    std::fill_n(*(abc+i), cols, sizeof(int)); 
} 

fill_nは知らないので、あなたは慎重にそのようにコーディングする必要があります。

私は読むことをお勧めします。 A proper way to create a matrix in c++

1

あなたはすでにあなたの問題を解決するために良い、実行可能な答えを持っているので、私はちょうど2つのポインタが標準パス;-)

から左右追加します

A)Boost.MultiArray

のドキュメントへのリンクだけであり、b)私はあなたがを使用することはお勧めしませんが、それはあなたが最初に試したかを理解するのに役立つかもしれない何かです。あなたのプロフィールはvisual studioタグを表示しているので、かもしれません。はwin32 apiでこれと連絡を取ります。その場合、ドキュメントでは通常、要素と "外側"ポインタポインタでfree()/ LocalFree()/ ...を使用せず、特別な関数を使用するように指示しています。
(注:私はこのコードをしようとしていないよかなりや巧妙になり、それは、cの寄せ集めと少しC++だ - っぽいジャンク;-))

const std::size_t rows = 3, cols =4; 

int main() 
{ 
    std::size_t x,y; 
    // allocate memory for 0...rows-1 int* pointers _and_ cols*rows ints 
    int **abc = (int**)malloc((rows*sizeof(int*)) + cols*rows*sizeof(int)); 

    // the memory behind abc is large enough to hold the pointers for abc[0...rows-1] 
    // + the actual data when accessing abc[0...rows-1][0....cols-1] 
    int* data = (int*)((abc+rows)); 
    // data now points to the memory right after the int*-pointer array 
    // i.e. &(abc[0][0]) and data should point to the same location when we're done: 
    // make abc[0] point to the first row (<-> data+(cols*0)), abc[1] point the second row (<-> data+(cols*1).... 
    for(y=0;y<rows; y++) { 
     abc[y] = &(data[y*cols]); 
    } 

    // now you can use abc almost like a stack 2d array 
    for(y=0; y<rows; y++) { 
     for (x=0; x<cols; x++) { 
      abc[y][x] = 127; 
     } 
    } 

    // and -since the memory block is continuos- you can also (with care) use memset 
    memset(&abc[0][0], 1, sizeof(int)*rows*cols); 

    // and with equal care .... 
    std::fill_n(&(abc[0][0]), rows*cols, 127); 

    // and get rid of the whole thing with just one call to free 
    free(abc); 

    return 0; 
} 
関連する問題