【问题标题】:How to use memset or fill_n to initialize a dynamic two dimensional array in C++如何在 C++ 中使用 memset 或 fill_n 初始化动态二维数组
【发布时间】:2016-07-30 02:44:56
【问题描述】:

我有一个动态创建的二维数组。

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

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

我想用一些值(比如 1)填充数组。我可以遍历每个项目并做到这一点。

但是有没有更简单的方法。我正在尝试使用memsetstd::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]

我在这里做错了什么?

【问题讨论】:

  • 退回到 C 可能是一种选择:int (*abc)[cols] = malloc(rows*sizeof(*abc)); memset(abc, 1, rows*sizeof(*abc)); 自 C99 以来是合法的 C,但在 C++ 中不可能很快实现。

标签: c++ multidimensional-array dynamic-arrays memset


【解决方案1】:

你可以使用vector:

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

您不能直接在abc 上使用std::fill_nmemset,它根本不起作用。您只能在子数组上使用其中一个:

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

【讨论】:

    【解决方案2】:

    我认为您的主要问题是您没有 int 值的数组。你有一个指向ints 的指针数组。

    如果我了解您在这里想要实现的目标,您可能应该从 int* abc = new int[rows * cols]; 开始并从那里开始工作。

    【讨论】:

      【解决方案3】:

      只需在已有的循环中使用 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++

      【讨论】:

        【解决方案4】:

        既然你已经有了解决问题的好、可行的答案,我想从标准路径左右添加两个指针;-)

        a) 只是指向Boost.MultiArray 文档的链接

        和 b) 是我不建议您使用的东西,但它可能会帮助您了解您最初尝试过的内容。由于您的个人资料显示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;
        }
        

        【讨论】:

          猜你喜欢
          • 2020-10-30
          • 2014-05-27
          • 2012-01-27
          • 2012-07-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多