new和delete以及malloc和free 二维数组

本文介绍了一段使用C语言实现的程序,该程序通过scanf函数读取字符和整数,并利用malloc动态分配内存来创建一个二维字符数组。文章详细展示了如何逐行逐字符地填充数组,以及如何释放分配的内存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

int main()
{
	char c,d;
	scanf("%c",&c);
	scanf("%c",&d);//如果输入了一个字符后按回车,则d为回车
	//scanf("%c%c",&c,&d);//同上
	printf("%c ",c);
	printf("%c ",d);

	int N;
	int M;
	scanf("%d",&N);
	scanf("%d",&M);
	char **img;
	img = (char **) malloc(sizeof(char*)*N);
	//img = new char *[N];
	char tmp;
	for (int i = 0; i < N; i++)
	{
		img[i] = (char*) malloc(sizeof(char)*M);
		//img[i] = new char[M];
		//scanf("%s",img[i]);//如果要忽略末尾的换行符,则用此方法
		for (int j = 0; j < M;j++)
		{
			scanf("%c",&img[i][j]);
		}
		scanf("%c",&tmp);//如果是一个个字符的输入,换行后再输入下一行,则要把这个换行符单独处理掉
	}
	
	for (int i = 0; i < N; i++)
	{
		free((void *)img[i]);
		//free(img[i]) //runtime error
	}
	free ((void *)img);
	//free(img)//normal


	/*for(int i=0;i<N;i++)
	{ 
		delete[] img[i]; 
	} 
	delete []img;*/
	return 0;
}

<think>我们正在讨论C语言中动态创建二维数组的方法。根据引用,常见的方法有使用malloc/freenew/delete(C++)。由于问题要求C语言,我们主要使用mallocfree。动态二维数组的创建通常有两种方式: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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值