C语言中动态申请连续的二维数组

本文介绍如何使用C语言动态申请并操作二维数组,包括内存分配、数据赋值和释放过程,通过实例演示了从申请到使用的完整流程。

      可以采用多申请一些指针,然后这一些指针分别指向后面数据区中对应的位置,如一个3*4int类型数组,我们先申请大小为sizeof(int*) * 3 + 3 * 4 * sizeof(int)的一维数组设为arr。然后arr[0]存放指向arr + sizeof(int*) * 3这个位置的指针,arr[1]存放指向arr + sizeof(int*) * 3 + 4 * sizeof(int)这个位置的指针, arr[2]存放指向arr + sizeof(int*) * 3 + 2 * 4 * sizeof(int)这个位置的指针

代码如下:
#include "StdAfx.h"
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h> 

// BYTE型颜色:RGB
typedef unsigned char  BYTE;
typedef struct tagBYTECOLORRGB
{
	BYTE red;
	BYTE green;
	BYTE blue;
}BYTECOLORRGB;

//动态申请二维数组  
template <typename T>  
T** malloc_Array2D(int row, int col)  
{  
	   int size = sizeof(T);  
	   int point_size = sizeof(T*);  
	   //先申请内存,其中point_size * row表示存放row个行指针  
	   T **arr = (T **) malloc(point_size * row + size * row * col);  
	   if (arr != NULL)  
	   {     
		   memset(arr, 0, point_size * row + size * row * col);  
		   T *head = (T*)((BYTECOLORRGB*)arr + point_size * row);  
		   while (row--)  
			            arr[row] = (T*)((BYTECOLORRGB*)head + row * col * size);  
	   }  
	   return (T**)arr;  
}  


//释放二维数组  
void free_Aarray2D(void **arr)  
{  
	if (arr != NULL)  
		free(arr);
	arr =NULL;
}  


int main()  
{  
	printf("请输入行列(以空格分开): ");  
	int nRow, nCol;  
    scanf("%d %d", &nRow, &nCol);  
    //动态申请连续的二维数组  
	BYTECOLORRGB **p = malloc_Array2D<BYTECOLORRGB>(nRow, nCol);  
	//为二维数组赋值     
	p[0][0].red = 20;
	printf("%4d ", p[0][0].red);
    free_Aarray2D((void**)p);  
    return 0;  
}  


<think>我们正在讨论C语言动态创建二维数组的方法。根据引用,常见的方法有使用malloc/free或new/delete(C++)。由于问题要求C语言,我们主要使用malloc和free。动态二维数组的创建通常有两种方式:1.使用指针数组:先申请一个指针数组,再为每个指针申请一维数组。2.使用连续内存:一次性申请所有元素所需的内存,然后通过计算索引来访问。下面分别给出示例:方法一:指针数组(不连续的内存)步骤:a.申请一个指针数组(行数)b.为每一行申请一维数组(列数)方法二:连续内存(模拟二维数组)步骤:a.一次性申请所有元素的内存(行数×列数)b.再申请一个指针数组,每个指针指向每一行的起始位置(这样可以使用双重索引,如arr[i][j])或者,也可以直接使用一维数组,然后通过索引计算(如arr[i*cols+j])来访问。我们将分别展示这两种方法。注意:动态分配的内存必须在使用后释放,避免内存泄漏。示例代码:方法一:指针数组(不连续)方法二:连续内存(使用指针数组指向连续内存)方法三:直接使用一维数组模拟(不通过二级指针,而是通过索引计算)但用户要求二维数组,所以我们主要展示前两种。另外,引用[3]提到了使用指针访问数组元素的方式,如*(a+i)访问一维数组,对于二维数组,我们可以用*(*(arr+i)+j)来访问。下面给出示例教程。</think>### C语言动态申请与使用二维数组教程 在C语言动态创建二维数组主要有两种方法,下面结合代码示例详细说明: #### 方法1:指针数组法(行指针独立分配) ```c #include <stdio.h> #include <stdlib.h> int main() { int rows = 3, cols = 4; // 1. 申请行指针数组 int **arr = (int **)malloc(rows * sizeof(int *)); if (arr == NULL) return 1; // 2. 为每行申请列空间 for (int i = 0; i < rows; i++) { arr[i] = (int *)malloc(cols * sizeof(int)); if (arr[i] == NULL) return 1; } // 3. 使用二维数组(赋值示例) for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { arr[i][j] = i * 10 + j; // 等价于 *(*(arr+i)+j) } } // 4. 打印验证 for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { printf("%2d ", arr[i][j]); } printf("\n"); } // 5. 释放内存(先释放列,再释放行) for (int i = 0; i < rows; i++) free(arr[i]); free(arr); return 0; } ``` **特点**: - 每行内存独立分配,可能不连续 - 支持标准`arr[i][j]`语法 - 释放时需要循环释放 #### 方法2:连续内存法(单次分配) ```c #include <stdio.h> #include <stdlib.h> int main() { int rows = 3, cols = 4; // 1. 一次性分配所有空间 int *data = (int *)malloc(rows * cols * sizeof(int)); if (data == NULL) return 1; // 2. 创建行指针数组 int **arr = (int **)malloc(rows * sizeof(int *)); if (arr == NULL) return 1; // 3. 设置行指针指向连续内存块 for (int i = 0; i < rows; i++) { arr[i] = data + i * cols; // 行首地址计算 } // 4. 使用二维数组(通过指针运算) for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { *(arr[i] + j) = i * 10 + j; // 等价于 arr[i][j] } } // 5. 打印验证 for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { printf("%2d ", arr[i][j]); } printf("\n"); } // 6. 释放内存(先释放行指针,再释放数据块) free(arr); free(data); return 0; } ``` **特点**: - 所有元素存储在连续内存中 - 访问效率更高,缓存友好 - 释放操作更简单 #### 关键注意事项: 1. **指针运算**:访问元素可使用`arr[i][j]`或`*(*(arr + i) + j)`[^3] 2. **内存对齐**:连续内存法保证内存连续性,适合需要连续存储的场景 3. **错误检查**:每次`malloc`后必须检查返回值 4. **释放顺序**: - 指针数组法:先释放所有`arr[i]`,再释放`arr` - 连续内存法:先释放`arr`,再释放`data` 5. **行偏移计算**:在连续内存法中,行首地址计算遵循`data + i * cols`[^2] > 两种方法输出结果均为: > 0 1 2 3 > 10 11 12 13 > 20 21 22 23
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值