搞懂C语言动态分配内存给一维数组和二维数组

1、一维数组动态分配内存:int num[5]

源码:

int main(void)
{
	// 使用动态内存分配一个数组为 int num[5] 
	int *num = NULL;
	int len = 5;
	num = (int *)malloc(len * sizeof(int));
	for (int i = 0; i < len; i++)
	{
		num[i] = i;
	}
	for (int i = 0; i < len; i++)
	{
		printf("num[%d] = %d, &num[%d] = %p\n", i, num[i], i, &num[i]);
	}
	if (num != NULL)
	{
		free(num);
		num = NULL;
	}
	return 0;
}


① num = (int *)malloc(len * sizeof(int));
在堆区分配了5个int型的内存空间,并将该内存空间的首元素地址返回给指针num,创建了一个数组为int num[5],如下图所示:
 

 

② 分配在堆区的内存空间地址是连续的,打印的结果如下: 

num[0] = 0, &num[0] = 01145B50
num[1] = 1, &num[1] = 01145B54
num[2] = 2, &num[2] = 01145B58
num[3] = 3, &num[3] = 01145B5C
num[4] = 4, &num[4] = 01145B60

地址是4个字节递增的,因为这里int型是4字节的,它跟在栈区定义数组 int num[5] 是一致的。

 

③ 在堆区动态分配的内存需要进行手动释放,不然会造成内存泄漏,使用free(num)。


 

 

2、二维数组动态分配内存:char ptr[5][30]

源码:

int main(void)
{
	int n = 5;
	// char *ptr[5];
	char **ptr = (char **)malloc(n * sizeof(char *));
	if (ptr == NULL)
	{
		printf("malloc failed!\n");
		return -1;
	}
	char buf[30];
	for (int i = 0; i < n; i++)
	{
		// char ptr[5][30]
		ptr[i] = (char *)malloc(30 * sizeof(char));
		sprintf(buf, "Test%d:%d\n", i, i);
		strcpy(ptr[i], buf);
	}
	for (int i = 0; i < n; i++)
	{
		printf("%s", ptr[i]);
	}
	for (int i = 0; i < n; i++)
	{
		if (ptr[i] != NULL)
		{
			free(ptr[i]);
			ptr[i] = NULL;
		}
	}
	if (ptr != NULL)
	{
		free(ptr);
		ptr = NULL;
	}
	system("pause");
	return 0;
}


① char **ptr = (char **)malloc(n * sizeof(char *));
在堆区分配了5个char *指针类型的内存空间,并将该内存空间的首元素地址返回给二级指针ptr,相当于char *ptr[5]。
注意:这里返回给二级指针是因为malloc分配完成后会将分配的内存空间首元素地址进行返回,而内存空间是5个char *的指针类型,即首元素是指针,返回的是指针的地址,所以需要使用二级指针取保存一级指针的地址。



② ptr[i] = (char *)malloc(30 * sizeof(char));
在上面因为只分配了一个在堆区的内存空间存放5个char *类型,但是每个指针需要的内存空间是还没有分配的,所以需要对这5个指针在堆区内再次进行分配内存空间为30个char类型,相当于分配了二维数组ptr[5][30],如下图:


③ 最后要释放在堆区分配的内存空间,不然会造成内存泄漏,释放顺序是先将ptr[0]-ptr[4]这5个分配的30个char类型字节的内存空间释放掉,接着再将二级指针ptr所指向在堆区分配的5个char *类型的内存空间给释放掉。

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值