2016-04-08 11 views
6

Ich habe ein 2D-Array dynamisch erstellt.Wie memset oder fill_n verwenden, um ein dynamisches zweidimensionales Array in C++ initialisieren

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

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

Ich mag das Array mit einem gewissen Wert füllen (zB 1). Ich kann über jeden Gegenstand schleifen und es tun.

Aber gibt es einen einfacheren Weg. Ich versuche memset und std::fill_n wie in this post erwähnt zu verwenden.

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

Mit memset stürzt mein Programm ab. Die Verwendung von fill_n gibt einen Kompilierungsfehler.

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

Was mache ich hier falsch?

+0

zurück zu C Dropping könnte eine Option sein: 'int (* abc) [Spalten] = malloc (rows * sizeof (* abc)); memset (abc, 1, rows * sizeof (* abc)); 'ist legal C seit C99, wird aber in C++ in absehbarer Zeit nicht mehr möglich sein. – cmaster

Antwort

5

Sie könnten nur vector verwenden:

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

Sie nicht std::fill_n oder memset auf abc direkt verwenden können, es wird einfach nicht funktionieren. Sie können nur entweder auf den Unterfeldern verwenden:

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); 
} 

Oder das Ganze machen eindimensionales:

int *abc = new int[rows * cols]; 
std::fill_n(abc, rows*cols, 1); 

Oder ich denke, man std::generate_n in Kombination mit std::fill_n verwenden könnte, aber dies scheint nur verwirrend:

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 danke! – Barry

3

ich denke, dass Ihr hier Hauptproblem ist, dass Sie nicht ein Array von int Werte haben. Sie haben ein Array von Zeigern zu int s.

Sie sollten wahrscheinlich mit int* abc = new int[rows * cols]; beginnen und von dort aus arbeiten, wenn ich verstehe, was Sie hier erreichen wollen.

2

Verwenden Sie einfach mit * innerhalb der Schleife Sie bereits haben:

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

fill_n weiß nicht, wo der Speicher den neuen int-Array abbildet, so dass Sie sorgfältig auf diese Weise Codierung sein muss.

Ich empfehle zu lesen: A proper way to create a matrix in c++

1

Da Sie bereits hat gute, tragfähige Antworten Ihr Problem zu lösen, ich möchte nur zwei Zeiger hinzuzufügen und aus dem Standard-Pfad rechts nach links ;-)

a) ist nur ein Link auf die Dokumentation von Boost.MultiArray

und b) ist etwas, was ich Sie nicht empfehlen verwenden, aber es könnte Ihnen helfen, zu verstehen, was Sie ursprünglich versucht haben. Und da Ihr Profil visual studio Tags zeigt, können Sie mit so etwas in der Win32 API in Kontakt kommen. Wenn dies der Fall ist, sagt die Dokumentation normalerweise, dass Sie free()/LocalFree()/... nicht für die Elemente und den "äußeren" Zeigerzeiger verwenden sollen, sondern eine spezielle Funktion verwenden sollen.
(Anmerkung: Ich versuche, diesen Code nicht aussehen zu lassen hübsch oder klug, es ist ein Mischmasch von c ist und ein wenig C++ - ish Junk ;-))

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; 
}