C++中如何使用memset或fill_n初始化动态二维数组
How to use memset or fill_n to initialize a dynamic two dimensional array in C++
我有一个动态创建的二维数组。
int **abc = new int*[rows];
for (uint32_t i = 0; i < rows; i++)
{
abc[i] = new int[cols];
}
我想用一些值(比如 1)填充数组。我可以遍历每个项目并执行它。
但是有没有更简单的方法。我正在尝试使用 memset
和 std::fill_n
,如 this post 中所述。
std::fill_n(abc, rows * cols, 1);
memset(abc, 1, rows * cols * sizeof(int));
使用 memset 使我的程序崩溃。使用 fill_n 会产生编译错误。
invalid conversion from 'int' to 'int*' [-fpermissive]
我做错了什么?
你可以只使用 vector
:
std::vector<std::vector<int>> abc(rows, std::vector<int>(cols, 1));
您不能直接在 abc
上使用 std::fill_n
或 memset
,它根本不起作用。您只能在子数组上使用其中之一:
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
的指针数组。
你可能应该从 int* abc = new int[rows * cols];
开始,如果我理解你在这里想要实现的目标的话。
只需在已有的循环中使用 with * 即可:
for (uint32_t i = 0; i < rows; i++)
{
abc[i] = new int[cols];
std::fill_n(*(abc+i), cols, sizeof(int));
}
fill_n 不知道内存映射新的 int 数组的位置,所以你必须小心编码。
我推荐阅读:
A proper way to create a matrix in c++
既然您已经找到了解决问题的有效可行答案,我只想从标准路径左右添加两个指针 ;-)
a) 只是 Boost.MultiArray
文档的 link
和 b) 是我不建议您使用的东西,但它可能会帮助您了解您最初尝试过的内容。由于您的个人资料显示 visual studio
标签,您 可能 在 win32 api 中接触到类似的东西。如果是这种情况,文档通常会告诉您不要在元素和 "outer" 指针上使用 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;
}
我有一个动态创建的二维数组。
int **abc = new int*[rows];
for (uint32_t i = 0; i < rows; i++)
{
abc[i] = new int[cols];
}
我想用一些值(比如 1)填充数组。我可以遍历每个项目并执行它。
但是有没有更简单的方法。我正在尝试使用 memset
和 std::fill_n
,如 this post 中所述。
std::fill_n(abc, rows * cols, 1);
memset(abc, 1, rows * cols * sizeof(int));
使用 memset 使我的程序崩溃。使用 fill_n 会产生编译错误。
invalid conversion from 'int' to 'int*' [-fpermissive]
我做错了什么?
你可以只使用 vector
:
std::vector<std::vector<int>> abc(rows, std::vector<int>(cols, 1));
您不能直接在 abc
上使用 std::fill_n
或 memset
,它根本不起作用。您只能在子数组上使用其中之一:
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
的指针数组。
你可能应该从 int* abc = new int[rows * cols];
开始,如果我理解你在这里想要实现的目标的话。
只需在已有的循环中使用 with * 即可:
for (uint32_t i = 0; i < rows; i++)
{
abc[i] = new int[cols];
std::fill_n(*(abc+i), cols, sizeof(int));
}
fill_n 不知道内存映射新的 int 数组的位置,所以你必须小心编码。
我推荐阅读: A proper way to create a matrix in c++
既然您已经找到了解决问题的有效可行答案,我只想从标准路径左右添加两个指针 ;-)
a) 只是 Boost.MultiArray
文档的 link和 b) 是我不建议您使用的东西,但它可能会帮助您了解您最初尝试过的内容。由于您的个人资料显示 visual studio
标签,您 可能 在 win32 api 中接触到类似的东西。如果是这种情况,文档通常会告诉您不要在元素和 "outer" 指针上使用 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;
}