简体   繁体   English

如何使用memset或fill_n在C ++中初始化动态二维数组

[英]How to use memset or fill_n to initialize a dynamic two dimensional array in C++

I have a 2D array created dynamically. 我有一个动态创建的2D数组。

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

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

I want to fill the array with some value (say 1). 我想用一些值填充数组(比如说1)。 I can loop over each item and do it. 我可以遍历每个项目并执行它。

But is there a simpler way. 但是有一种更简单的方法。 I am trying to use memset and std::fill_n as mentioned in this post . 我正在尝试使用这篇文章中提到的memsetstd::fill_n

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

Using memset crashes my program. 使用memset会崩溃我的程序。 Using fill_n gives a compile error. 使用fill_n会产生编译错误。

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

What am I doing wrong here ? 我在这做错了什么?

You could just use vector : 你可以使用vector

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

You cannot use std::fill_n or memset on abc directly, it simply will not work. 你不能直接在abc上使用std::fill_nmemset ,它根本不起作用。 You can only use either on the sub-arrays: 您只能在子数组上使用:

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

Or make the whole thing single-dimensional: 或者使整个事物成为一维的:

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

Or I guess you could use std::generate_n in combination with std::fill_n , but this just seems confusing: 或者我猜你可以将std::generate_nstd::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;
});

I think that your main problem here is that you don't have an array of int values. 我认为你的主要问题是你没有一个int值数组。 You have an array of pointers to int s. 你有一个指向int的指针数组。

You probably should start with int* abc = new int[rows * cols]; 你可能应该从int* abc = new int[rows * cols]; and work from there, if I understand what you are trying to achieve here. 如果我明白你想要在这里实现什么,那就从那里开始工作。

Just use with * inside the loop you already have: 只需在已经拥有的循环中使用*:

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

fill_n don't know where the memory maps the new int array, so you must be carefully coding that way. fill_n不知道内存映射新int数组的位置,所以你必须仔细编码。

I recommend to read: A proper way to create a matrix in c++ 我建议阅读: 在c ++中创建矩阵的正确方法

Since you've already got good, workable answers to solve your problem, I want to add just two pointers left and right from the standard path ;-) 既然你已经有了解决问题的好的,可行的答案,我想在标准路径中左右两点添加两个指针;-)

a) is just a link to the documentation of Boost.MultiArray a)只是Boost.MultiArray文档的链接

and b) is something I don't recommend you use , but it might help you to understand what you've initially tried. 和b)是我不建议你使用的东西,但它可以帮助你理解你最初尝试过的东西。 And since your profile shows visual studio tags, you might come in contact with something like this in the win32 api. 由于您的个人资料显示了visual studio标签,因此您可能会在win32 api中接触到类似的内容。 If that is the case the documentation usually tells you not to use free()/LocalFree()/... on the elements and the "outer" pointer-pointer but to use a specialized function. 如果是这种情况,文档通常会告诉您不要在元素和“外部”指针指针上使用free()/ LocalFree()/ ...但是要使用专门的函数。
(note: I'm not trying to make this code look pretty or clever; it's a mishmash of c and a little c++-ish junk ;-)) (注意:我不是试图使这段代码看起来漂亮或聪明;它是c和c ++的混合物 - 一点点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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM