1

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??

  • you allocate N separate blocks of M ints dynamically; those could be located anywhere with gaps inbetween or even with the last block of integers being located before the first one so you may just to memory not belonging to you. In the second example you make use of the fact that compilers usually uses one continuous block of memory to store a 2d array in, but there's no guarantee; both programs have undefined behaviour... – fabian Mar 27 '22 at 17:30

4 Answers4

2

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));
QWERTYL
  • 1,355
  • 1
  • 7
  • 11
  • *there is no reason the array should be contiguous* -- Not if the array is created [to be contiguous](https://stackoverflow.com/questions/21943621/how-to-create-a-contiguous-2d-array-in-c/21944048#21944048). – PaulMcKenzie Mar 27 '22 at 18:16
1

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_;
PaulMcKenzie
  • 34,698
  • 4
  • 24
  • 45
0

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);
}
ChrisMM
  • 8,448
  • 13
  • 29
  • 48
-3

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

Drago Ban
  • 105
  • 1
  • 8
  • 1
    Actually, in STL functions, ranges are always from [begin, end) rather than [begin, end]. Basically begin is included in the range but end is not (only the element right before end). – QWERTYL Mar 27 '22 at 17:33