我有以下的 C
代码:
int *a;
size_t size = 2000*sizeof(int);
a = malloc(size);
这个代码运行良好。但是如果我有以下代码:
char **b = malloc(2000*sizeof *b);
假设每个元素的长度都不同,那么如何对b执行与 a
相同的操作?即以下代码是否正确?
char *c;
size_t size = 2000*sizeof(char *);
c = malloc(size);
首先,您需要分配指针数组,如 char **c = malloc( N * sizeof( char* ))
,然后为每个行分别调用malloc
来进行分配,可能需要在循环中进行:
/* N is the number of rows */
/* note: c is char** */
if (( c = malloc( N*sizeof( char* ))) == NULL )
{ /* error */ }
for ( i = 0; i < N; i++ )
{
/* x_i here is the size of given row, no need to
* multiply by sizeof( char ), it's always 1
*/
if (( c[i] = malloc( x_i )) == NULL )
{ /* error */ }
/* probably init the row here */
}
/* access matrix elements: c[i] give you a pointer
* to the row array, c[i][j] indexes an element
*/
c[i][j] = 'a';
如果您知道元素的总数(例如 N*M
),您可以进行单个分配。
T **a = malloc(sizeof *a * N);
if (a)
{
for (i = 0; i < N; i++)
{
a[i] = malloc(sizeof *a[i] * M);
}
}
T **a = malloc(sizeof *a * N);
if (a)
{
for (i = 0; i < N; i++)
{
a[i] = malloc(sizeof *a[i] * length_for_this_element);
}
}
a[i]
,然后再释放a
。 - John Bodechar a[10][20]
的等效内存分配如下所示。
char **a;
a=malloc(10*sizeof(char *));
for(i=0;i<10;i++)
a[i]=malloc(20*sizeof(char));
我希望这看起来简单易懂。
另一种方法是分配一个连续的内存块,其中包括指向行的指针的头块和存储实际数据的主体块。然后只需通过在每行基础上将主体内存中的地址分配给头块中的指针来标记内存。它看起来像下面这样:
int** 2dAlloc(int rows, int* columns) {
int header = rows * sizeof(int*);
int body = 0;
for(int i=0; i<rows; body+=columnSizes[i++]) {
}
body*=sizeof(int);
int** rowptr = (int**)malloc(header + body);
int* buf = (int*)(rowptr + rows);
rowptr[0] = buf;
int k;
for(k = 1; k < rows; ++k) {
rowptr[k] = rowptr[k-1] + columns[k-1];
}
return rowptr;
}
int main() {
// specifying column amount on per-row basis
int columns[] = {1,2,3};
int rows = sizeof(columns)/sizeof(int);
int** matrix = 2dAlloc(rows, &columns);
// using allocated array
for(int i = 0; i<rows; ++i) {
for(int j = 0; j<columns[i]; ++j) {
cout<<matrix[i][j]<<", ";
}
cout<<endl;
}
// now it is time to get rid of allocated
// memory in only one call to "free"
free matrix;
}
这种方法的优势在于优雅地释放内存,并能够使用类似数组的符号来访问生成的二维数组中的元素。
double
的第一列行上开始一个未对齐的边界。这一点非常重要,需要加以考虑,因为不正确的数据对齐可能会导致总线错误。通用解决方案应确保数据行从8字节边界开始,并在将行指针分配给主指针段时进行额外分配空间并相应地进行调整。 - WhozCraigcolumnSizes[]
? - user2284570int totalLength = 0;
for_every_element_in_b {
totalLength += length_of_this_b_in_bytes;
}
return malloc(totalLength);
2-D 数组动态内存分配
int **a,i;
// for any number of rows & columns this will work
a = malloc(rows*sizeof(int *));
for(i=0;i<rows;i++)
*(a+i) = malloc(cols*sizeof(int));
malloc不会在特定边界上分配内存,因此必须假定它在字节边界上进行分配。
如果将返回的指针转换为其他类型,则不能使用该指针,因为访问该指针可能会导致CPU发生内存访问冲突,并且应用程序将立即关闭。
malloc
都有一个free
。您需要循环遍历char*
变量并释放它们,然后释放char**
。 - erickrf