Как использовать memset или fill n для инициализации динамического двумерного массива в C++
у меня есть 2D-массив, созданный динамически.
int **abc = new int*[rows];
for (uint32_t i = 0; i < rows; i++)
{
abc[i] = new int[cols];
}
Я хочу заполнить массив некоторым значением (скажем, 1). Я могу зациклиться на каждом элементе и сделать это.
но есть более простой способ. Я пытаюсь использовать memset
и std::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]
что я здесь делаю не так ?
4 ответов
вы можете просто использовать vector
:
std::vector<std::vector<int>> abc(rows, std::vector<int>(cols, 1));
вы не можете использовать std::fill_n
или memset
on abc
непосредственно, это просто не будет работать. Вы можете использовать только либо на суб-массивах:
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 * cols];
std::fill_n(abc, rows*cols, 1);
или я думаю, вы могли бы использовать std::generate_n
в сочетании с std::fill_n
, но это просто кажется запутанным:
int **abc = new int*[rows];
std::generate_n(abc, rows, [cols]{
int* row = new int[cols];
std::fill_n(row, cols, 1);
return row;
});
Я думаю, что ваша главная проблема здесь в том, что у вас нет массива int
значения. У вас есть массив указателей на int
s.
вы, вероятно, должны начать с int* abc = new int[rows * cols];
и работайте оттуда, если я понимаю, чего вы пытаетесь достичь здесь.
просто используйте С * внутри цикла, который у вас уже есть:
for (uint32_t i = 0; i < rows; i++)
{
abc[i] = new int[cols];
std::fill_n(*(abc+i), cols, sizeof(int));
}
fill_n не знают, где память отображает новый массив int, поэтому вы должны тщательно кодировать таким образом.
Я рекомендую прочитать: правильный способ создания матрицы в c++
поскольку у вас уже есть хорошие, работоспособные ответы для решения вашей проблемы, я хочу добавить только два указателя влево и вправо от стандартного пути ;-)
a) - это просто ссылка на документацию импульс.MultiArray
и Б) это то, что я не рекомендуется использовать, но это может помочь вам понять, что вы изначально пытались. И так как ваш профиль показывает 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;
}