c++ - 快速将双指针数组转换为单指针,可能可以是连续的

标签 c++ arrays c++11

我正在使用一个库,该库将图像作为大二维数组 int** 返回。我需要将其转换为 int* 一维数组。我想我已经通过复制内存块成功地做到了相当快的速度:

// have int labels** as 2D array, also have rows and cols 

//create 1D array
int *labels1D = new int[rows*cols];

//copy contents
for(int i = 0; i < rows; i++) {        
    // Here I don't know anything about how those arrays were allocated
    // Maybe std::copy would handle it for me?
    std::copy_n(labels[i], cols, labels1D + i*cols);
}

所以第一个问题是我是否可以在这里做得更好?假设图书馆是一个黑匣子,这里的一切都安全吗?


我不想太多修改库代码,但我还发现了我的侧库 this->currentLabels 中的源数组是如何创建的:

int** currentLabels; //in class declaration
...
// in the code
this->currentLabels = new int*[this->height];

for (int i = 0; i < this->height; ++i) {
    this->currentLabels[i] = new int[this->width];

    for (int j = 0; j < this->width; ++j) {
     // some code for setting the value
        }

    }

看起来行和列的值是已知的。

所以第二个问题是:我可以修改这段代码以使其在一个内存块中分配二维数组吗:

this->currentLabels = malloc(nrows*sizeof(int*) + (nrows*(ncolumns*sizeof(int)));

允许我以某种方式将其映射到我的一维数组而不复制内存?


编辑:感谢@SamVarshavchik,映射似乎按以下方式工作:

// Allocate 2-D array as one block:

// Allocate pointers:
int** labels = new int*[rows];
// Allocate data:
auto ptr=new int[rows*cols];

for(int i = 0; i < rows; i++) {
    labels[i] = &ptr[i*cols];
}

// fill with values ranging 0 to certain number
for(int i = 0; i < rows; i++){
    for(int j = 0; j < cols; j++){
        // the code for setting the values
        labels[i][j] = i+j;
    }
}    

// have int labels** as 2D array, also have rows and cols 

//create 1D array
int *labels1D; // = new int[rows*cols];

//assign contents:
labels1D = &labels[0][0];

在库代码中销毁它的正确方法似乎是

delete[] ptr;  //user2079303 fixed
delete[] labels;

最佳答案

So the first question is whether I can do something better here?

您可以使用std::vector使内存管理更安全、更简单。我认为没有太多需要改进的地方。

The problem is that I need to send int * into another object (OpenCV Mat constructor) so I'm limited with exactly those types. Thanks anyway!

这不是问题。您可以使用 vector 的data成员函数,它返回一个指向内部数组的指针,您可以将其发送到另一个项目中。


So the second question is: can I modify this code to make it allocate the 2D array in one memory block:

我假设您绑定(bind)到需要您传递 int** 的接口(interface)。

如果您可以接受两次分配,那就很简单:首先分配适当大小的指针数组。然后分配一个包含所有值的平面数组,并将其分配给指针数组的第一个元素。然后将其余指针分配到值数组的正确位置。

单个分配是可能的,但很棘手。您可以为指针数组和值数组分配一个足够大的原始 char 数组,并使用放置 new 进行构造。这很棘手,因为它的级别非常低,并且您必须确保数组正确对齐,并且必须分配额外的空间以使对齐成为可能。这在具有 aligned_alloc 的 C 中更容易实现(似乎也在即将推出的 C++17 中)。


The right way to destroy it in the library code seems to be

delete ptr;
delete labels;

不,这似乎是错误的方式。删除用new[]分配的内存的正确方法是delete[]

关于c++ - 快速将双指针数组转换为单指针,可能可以是连续的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41371204/

相关文章:

c++ - STL优先级队列中的堆管理是否调用复制构造函数?

c++ - 就地构造一个包含元素的 vector

c++ - 如何在 C++ 函数中将静态数组初始化为某个值?

c++11 - std::map emplace gcc 4.8.2

python - 如何为 numpy 矩阵生成干净的 x 和 y 轴?

java - 一维数组遇到问题

c++ - 像 typedef 一样使用 decltype

c++ - 使用 Boost 统一生成随机实数

c++ - 指向结构的指针如何工作?

java - 尝试将 JSONArray 转换为 JSONObject