我想构建2D数组而无需执行许多free()操作。
#include <iostream>
#define un unsigned
#define ln long
un ln ** array_builder(un ln rows, un ln cols)
{
register const un ln row_memory = cols * sizeof(un ln);
auto array = (un ln **) malloc( rows * ( sizeof(un ln *) + row_memory ) );
// First line: The bytes of memory required to store a single row in the array
// Second line: We want to store all the pointers in the single array
auto pointer = (void *) array[0]; // sizeof(void *) == 1. It is convenient for our purposes
pointer += rows * sizeof(un ln *); /* Thus we skip the first pointers in the array (their amount equals 'rows').
This space is considered to store pointers of array[row] type */
for (un ln int i = 0; i < rows; i++)
{
array[i] = (un ln *) pointer; // We write pointers to each row in the array[row]
pointer += row_memory;
}
return array;
// We've built 2D-array. Now we can access to the elements of this array by convenient way as array[row][col]
// Don't forget to free(array) after use
}
但是这个程序工作不正确。例如,当我尝试通过数组[row] [col] = some_value更改某个值时,每次都会使程序在不同的地方崩溃。
答案 0 :(得分:3)
在C ++中,不使用malloc和free,也不使用等效的new和delete。一个人会使用正确的RAII,即没有手动释放资源。 对于二维数组,可以使用如下的单个字段:
std::vector<int> data;
data.resize(width * height);
//in case you know the amount of data at compile time use a static sized field
std::array<int, width * heigth> data;
//access a single cell
int cell = data[y * width + x];
//or obtain a pointer to a row of cells
int *rowptr = &data[y * width];
int cellinrow = rowptr[x];
这比分配多行更节省空间和时间。
在C中,您可以使用malloc等效地分配单个int块或使用静态大小的int [width * height]数组;
请注意,不要混用C和C ++,也不要使用register关键字,也不要使用lazy #defines
答案 1 :(得分:0)
你做不到。编译器需要知道要返回的类型,这需要内部数组的大小。另外,无论如何你都无法返回数组。
你能做的就是做一个为你做的课。你可以称之为vector
或其他东西。让它负责分配和解除分配某种类型的动态数组...然后将一个放在另一个内部,如下所示:
vector<vector<unsigned long>> {rows, vector<unsigned long>{cols,0}};
如果您仔细阅读Internet上的C ++教程和参考资料,您可能会发现某人已经写过这样的内容。
答案 2 :(得分:0)
假二维数组的算法unsigned long **
- 指向unsigned long
的指针
分配需要
1)指针数组array
有足够的内存
2)可能有一些填充用于unsigned long
的对齐
3)对rows*cols
unsigned long
记忆
这可以通过1次分配完成,因此只需要1 free()
。
指定array
元素以指向分配的第3部分。请记住对齐要求。
不清楚C ++代码为什么会这样。
OP的方法类似,但缺乏对齐考虑因素。如果指针窄于unsigned long
或在其他情况下,这可能会导致代码崩溃。
-
一些未经测试的C ++代码以&#34; C-style&#34;的方式使用malloc()
。
typedef unsigned long data_t;
data_t **alloc_2Ddata(size_t rows, size_t cols) {
data_t **a;
size_t row_ptrs_size = sizeof *a * rows;
size_t data_size = sizeof **a * rows * cols;
size_t pad = (sizeof **a - row_ptrs_size % sizeof **a) % sizeof **a;
a = (data_t **) malloc(row_ptrs_size + pad + data_size);
if (a) {
data_t *data = (data_t*) (((char*) a) + row_ptrs_size + pad);
for (size_t r = 0; r < rows; r++) {
a[r] = data;
data += cols;
}
}
return a;
}