How do I initialize dynamic allocated 2D array in C++

Viewed 173

I want to dynamically generate a two-dimensional array and initialize it to a specific integer value.So I coded it as follows.

#include <vector>
#include <algorithm>
#include <stdio.h>
#include <iostream>
#include <string>
#include <stack>
#include <queue>
#include <tuple>
using namespace std;

int main(){
    
// map 입력받기
int N,M;
cin>> N >> M;

int** map_= new int*[N];
for(int i=0; i< N; i++){
    map_[i]=new int[M];
}
fill(&map_[0][0], &map_[N][M], 2);
cout << " map[0][0] " << map_[0][0]  << endl;
int** visit= new int*[N];
for(int i=0; i< N; i++){
    visit[i]=new int[M];
}
fill(&visit[0][0], &visit[N-1][M-1], 0); // -1 : 진입 불가, 0 : 방문 안함, 1>= : 방문   


return 0;
}

A segmenation error occurs. What's the reason? please reply

The below code generated in a static array works.

#include <iostream>
#define MAX 5

using namespace std;

int matrix[MAX][MAX] = {0,};

int main(){
    fill(&matrix[0][0], &matrix[MAX][MAX], 2);

    for (int i=0; i<MAX; ++i){
        for (int j=0; j<MAX; ++j){
            cout << matrix[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

what is difference??

4 Answers

Since map_ is an array of pointers, there is no reason the array should be contiguous. The first pointer that's allocated may point to memory location 5, and the next to 352+M rather than 5+M. The solution is to use a vector of vectors instead of an array:

std::vector<std::vector<int>> map_(N, std::vector<int>(M, initial_value));

In your case, you would do:

std::vector<std::vector<int>> map_(N, std::vector<int>(M, 2));

The issue is as pointed out in the other answers, those individual rows are not in contiguous memory.

Based on a simplified version of this answer, if you want your code to work, then you should allocate your array similar to this:

int** map_= new int*[N];
int* mapPool = new int[N*M];
for(int i=0; i< N; i++, mapPool += M)
    map_[i] = mapPool;

The above creates a contiguous array, mapPool, and basically points all the row pointers to the right spot in mapPool.

Now the call to std::fill will work correctly:

fill(&map_[0][0], &map_[N-1][M], 2);

Of course, to deallocate the memory just requires two calls:

delete [] map_[0];
delete [] map_;

Static 2D arrays are stored consecutively in memory (essentially being a single dimensional array of size N * M), thus the fill function works fine on them. Contrarily, dynamic array are not stored the same way, each row could be stored anywhere in memory, and thus fill will not work on them. You will need to loop over the array yourself, and fill each row individually.

Example:

int** map_= new int*[N];
for(int i=0; i< N; i++) {
    map_[i]=new int[M];
    fill(&map_[i][0], &map_[i][M], 2);
}

I think the error in the first fill() function , please try &map_[N-1][M-1] instead of &map_[N][M]

Related