使用单次调用 malloc 为 C 89/90 中未知数据类型的二维数组动态分配连续的内存块
dynamically allocate contiguous block of memory for 2D array of unknown data type in C 89/90 using single call to malloc
我必须动态分配一个连续的存储块来保存任意数据类型的二维数组。
它只能使用一次调用 malloc
.
部分内存必须包含 "pointer to data type" 的混合数据类型和数据类型本身。
任意数据类型称为 Type
。
完全披露:是的,这是一项任务。为了弄清楚这一点,我已经为此苦苦思索了 30 多个小时。我不能使用 C99+ 标准。它必须是 Pre-C99。
到目前为止我有这个:
Type **Create2D(size_t rows, size_t cols) {
Type **ptr = (Type **)SafeMalloc(rows * sizeof(Type*) + rows * cols * sizeof(Type));
// rows*sizeof(Type*) is total memory needed for the elements to store the pointers.
// rows*cols*sizeof(Type) is the memory needed to store the actual array data
// The sum of the above two gives the total amount of contiguous memory needed
int index;
for (index = 0; index < (int)rows; index++)
ptr[index] = &ptr + rows*sizeof(Type *) + index * cols * sizeof(Type);
// in my mind, this assigns the pointers to the address of each column
// to the first address blocks allocated by malloc
}
Type
数据类型由提供的头文件使用 typedef
定义如下:
#define ELEMENTS 9
typedef signed char Type[ELEMENTS];
#undef ELEMENTS
SafeMalloc 函数只包含错误检查和 malloc 调用
static Type **SafeMalloc(size_t size) {
void *vp;
if ((vp = malloc(size)) == NULL) {
fputs("Out of memory\n", stderr);
exit(EXIT_FAILURE);
}
return(vp);
}
我的 Create2D 函数从 main 调用如下,其中 rows
和 cols
设置为 for 循环提供的不同值,以便它们通过列出的每个 运行代码在这里:
Type **ppobj;
int rows, cols;
ppobj = Create2D((size_t)rows, (size_t)cols);
数组在此处的另一个循环中被调用和测试:
int x = Test2D(ppObj, rows, cols);
定义为:
int Test2D(Type **ppObj, int dim0, int dim1) {
signed char testValue;
int row, col, ix;
Type item;
testValue = SCHAR_MIN;
for (row = 0; row < dim0; ++row) {
for (col = 0; col < dim1; ++col) {
for (ix = 0; ix < (int)(sizeof(item) / sizeof(item[0])); ++ix) {
ppObj[row][col][ix] = testValue;
// throws an exception in above step while stepping through at col = 1.
if (testValue == SCHAR_MAX)
testValue = SCHAR_MIN;
else
++testValue;
}
}
}
....
}
最后,我觉得我所拥有的已经很接近了。给定一个 1x27 数组,它将通过此操作,但是当我调用释放内存的函数然后调用 2x26 数组时,它将在上述步骤中出错。它进入了 3x25 阵列并且在上面也出现了错误。我的免费功能如下所示:
void Free2D(void *ptr) {
free(ptr);
}
它是使用这个语法调用的,来自上面的主函数:
Free2D((void *)ppObj);
我也 运行 它通过并看到 dim1
变量在嵌套的 for 循环中间从它的设置值从传递的参数变化到像 1830342 或一些种类。这让我相信我没有正确使用 free()
函数。
您的代码几乎是正确的,计算 ptr[index]
的公式不正确:您必须计算从 ptr
转换为字节指针的字节偏移量。
这是一个更好的版本:
Type **Create2D(size_t rows, size_t cols) {
Type **ptr = (Type **)SafeMalloc(rows * sizeof(Type*) + rows * cols * sizeof(Type));
// rows*sizeof(Type*) is total memory needed for the elements to store the pointers.
// rows*cols*sizeof(Type) is the memory needed to store the actual array data
// The sum of the above two gives the total amount of contiguous memory needed
size_t index;
for (index = 0; index < rows; index++) {
ptr[index] = (Type*)((unsigned char*)ptr + rows * sizeof(Type *) + index * cols * sizeof(Type));
// in my mind, this assigns the pointers to the address of each column
// to the first address blocks allocated by malloc
}
return ptr;
}
仍然存在潜在的对齐问题:Type
可能需要比 Type*
更严格的对齐。为了解决这个问题,您可以单独计算索引大小,并将数据部分对齐到 Type
:
大小的倍数
Type **Create2D(size_t rows, size_t cols) {
size_t index_size = (size_t)((unsigned long long)(rows * sizeof(Type*)) * sizeof(Type) / sizeof(Type));
Type **ptr = (Type **)SafeMalloc(index_size + rows * cols * sizeof(Type));
// index_size is total memory needed for the elements to store the pointers.
// rows*cols*sizeof(Type) is the memory needed to store the actual array data
// The sum of the above two gives the total amount of contiguous memory needed
size_t index;
for (index = 0; index < rows; index++) {
ptr[index] = (Type*)((unsigned char*)ptr + index_size + index * cols * sizeof(Type));
}
return ptr;
}
我必须动态分配一个连续的存储块来保存任意数据类型的二维数组。
它只能使用一次调用 malloc
.
部分内存必须包含 "pointer to data type" 的混合数据类型和数据类型本身。
任意数据类型称为 Type
。
完全披露:是的,这是一项任务。为了弄清楚这一点,我已经为此苦苦思索了 30 多个小时。我不能使用 C99+ 标准。它必须是 Pre-C99。
到目前为止我有这个:
Type **Create2D(size_t rows, size_t cols) {
Type **ptr = (Type **)SafeMalloc(rows * sizeof(Type*) + rows * cols * sizeof(Type));
// rows*sizeof(Type*) is total memory needed for the elements to store the pointers.
// rows*cols*sizeof(Type) is the memory needed to store the actual array data
// The sum of the above two gives the total amount of contiguous memory needed
int index;
for (index = 0; index < (int)rows; index++)
ptr[index] = &ptr + rows*sizeof(Type *) + index * cols * sizeof(Type);
// in my mind, this assigns the pointers to the address of each column
// to the first address blocks allocated by malloc
}
Type
数据类型由提供的头文件使用 typedef
定义如下:
#define ELEMENTS 9
typedef signed char Type[ELEMENTS];
#undef ELEMENTS
SafeMalloc 函数只包含错误检查和 malloc 调用
static Type **SafeMalloc(size_t size) {
void *vp;
if ((vp = malloc(size)) == NULL) {
fputs("Out of memory\n", stderr);
exit(EXIT_FAILURE);
}
return(vp);
}
我的 Create2D 函数从 main 调用如下,其中 rows
和 cols
设置为 for 循环提供的不同值,以便它们通过列出的每个 运行代码在这里:
Type **ppobj;
int rows, cols;
ppobj = Create2D((size_t)rows, (size_t)cols);
数组在此处的另一个循环中被调用和测试:
int x = Test2D(ppObj, rows, cols);
定义为:
int Test2D(Type **ppObj, int dim0, int dim1) {
signed char testValue;
int row, col, ix;
Type item;
testValue = SCHAR_MIN;
for (row = 0; row < dim0; ++row) {
for (col = 0; col < dim1; ++col) {
for (ix = 0; ix < (int)(sizeof(item) / sizeof(item[0])); ++ix) {
ppObj[row][col][ix] = testValue;
// throws an exception in above step while stepping through at col = 1.
if (testValue == SCHAR_MAX)
testValue = SCHAR_MIN;
else
++testValue;
}
}
}
....
}
最后,我觉得我所拥有的已经很接近了。给定一个 1x27 数组,它将通过此操作,但是当我调用释放内存的函数然后调用 2x26 数组时,它将在上述步骤中出错。它进入了 3x25 阵列并且在上面也出现了错误。我的免费功能如下所示:
void Free2D(void *ptr) {
free(ptr);
}
它是使用这个语法调用的,来自上面的主函数:
Free2D((void *)ppObj);
我也 运行 它通过并看到 dim1
变量在嵌套的 for 循环中间从它的设置值从传递的参数变化到像 1830342 或一些种类。这让我相信我没有正确使用 free()
函数。
您的代码几乎是正确的,计算 ptr[index]
的公式不正确:您必须计算从 ptr
转换为字节指针的字节偏移量。
这是一个更好的版本:
Type **Create2D(size_t rows, size_t cols) {
Type **ptr = (Type **)SafeMalloc(rows * sizeof(Type*) + rows * cols * sizeof(Type));
// rows*sizeof(Type*) is total memory needed for the elements to store the pointers.
// rows*cols*sizeof(Type) is the memory needed to store the actual array data
// The sum of the above two gives the total amount of contiguous memory needed
size_t index;
for (index = 0; index < rows; index++) {
ptr[index] = (Type*)((unsigned char*)ptr + rows * sizeof(Type *) + index * cols * sizeof(Type));
// in my mind, this assigns the pointers to the address of each column
// to the first address blocks allocated by malloc
}
return ptr;
}
仍然存在潜在的对齐问题:Type
可能需要比 Type*
更严格的对齐。为了解决这个问题,您可以单独计算索引大小,并将数据部分对齐到 Type
:
Type **Create2D(size_t rows, size_t cols) {
size_t index_size = (size_t)((unsigned long long)(rows * sizeof(Type*)) * sizeof(Type) / sizeof(Type));
Type **ptr = (Type **)SafeMalloc(index_size + rows * cols * sizeof(Type));
// index_size is total memory needed for the elements to store the pointers.
// rows*cols*sizeof(Type) is the memory needed to store the actual array data
// The sum of the above two gives the total amount of contiguous memory needed
size_t index;
for (index = 0; index < rows; index++) {
ptr[index] = (Type*)((unsigned char*)ptr + index_size + index * cols * sizeof(Type));
}
return ptr;
}