C语言 子函数调malloc申请内存返回给主函数使用——可行,但要注意

一般情况,子函数中动态申请内存,将地址返回给主函数,理论上应该也是可以的,需要子函数返回动态内存地址,主函数实参是相应的地址变量即可。只不过,主函数实参传入子函数之前,可能会将指针置空,那么,子函数就不能动态申请内存了。

如下例子:

C语言进阶---动态内存管理_c语言怎么遍历动态申请里面的内容-CSDN博客

4.几个经典的面试题

4.1 题目1:
复制代码
void Getmemory(char* p)//形参是实参的一份临时拷贝 p是指针变量 p指向NULL *p是NULL
{
	p = (char*)malloc(100);//p由指向NULL 变为指向malloc开辟空间的起始地址
}
void Test(void)
{
	char* str = NULL;
	GetMemory(str);//传的是实参
	strcpy(str, "helllo world");
	printf(str);
}
//程序会崩溃无法打印

更正:通过传实参的地址来找到实参在内存当中的位置然后再改变实参的值:

复制代码
void GetMemory(char** p)//char**p接收str的地址,是一个二级指针
{
	*p = (char*)malloc(100);//*p==str 由指向NULL 变为指向malloc开辟空间的起始地址
}
void Test(void)
{
	char* str = NULL;
	GetMemory(&str);//转str的地址
	strcpy(str, "helllo world");
	printf(str);
	free(str);
	str = NULL;
}
int main()
{
	Test();
	return 0;
}
//程序会正常打印"hello world"

另一个传地址的例子:

4.2题目2:

返回栈空间问题:

复制代码
char* GetMemory(void)
{
	char p [] = "hello world";//栈空间开辟数组
	return p;//p放在寄存器当中,这个函数可以成功返回数组名p,也就是数组的首元素地址

}
void Test(void)
{
	char* str = NULL;
	str = GetMemory();
	printf(str);
}
int main()
{
	Test();
	return 0;
}
//栈空间在用完之后会被系统回收,因此创建的数组p在GetMemory调用完之后就已经被销毁无法使用了
//str属于是野指针去访问了一块被销毁的空间,因此会打印一些随机值

改为:

复制代码
int* test()
{
	int a = 10;
	return &a;//a的地址被存放在寄存器当中
}
int main()
{
	int* p = test();//p接收到a的地址
	printf("%d\n", *p);//p已经是野指针  打印10 因为调用test的栈空间还没有被覆盖
	printf("%d\n", *p);// 打印随机值 有一次调用test函数,栈空间被新随机值给覆盖
	return 0;
}

另外,上面所说子函数动态申请内存给主函数用,主函数在使用完要释放。释放后最好置空,否则,其是个野指针,可能会导致错误。

4.3题目3:
复制代码
void GetMemory(char** p, int num)
{
    assert(*p);
	*p = (char*)malloc(num);
}
void tset(void)
{
	char* str = NULL;
	GetMemory(&str, 100);
	strcpy(str, "hello");
	printf(str);
	//free释放
	free(str);
	str = NULL;
}
int main()
{
	test();
	return 0;
}

改正:

复制代码
void test(void)
{
	char* str = (char*)malloc(100);
	strcpy(str, "hello");
	free(str);//free释放
	str = NULL;//置空
	if (str != NULL)
	{
		strcpy(str, "world");
		printf(str);//无法打印
	}
}
int main()
{
	test();
	return 0;
}
相关推荐
不正经学生16 小时前
C语言指针进阶:const 和野指针——给指针加锁,向野指针宣战
c语言·开发语言·c++·算法·c#
多弗朗皮卡丘17 小时前
C语言梦开始的地方3
c语言·开发语言
天空'之城1 天前
C 语言工业级通用组件手写 24:互补滤波
c语言·开发语言·互补滤波·嵌入式算法·工业级组件
stevenseahang1 天前
C语言标准演化史:从K&R到GNU,谁才是正统?
c语言·gnu·可移植性·标准演化·ansic
别动我齐刘海2 天前
Day6 unitree_G1人形机器人GMR—— MotionInput
c语言·c++·人工智能·学习·机器学习·机器人·github
AI科技星2 天前
曲率‑挠率与 $\boldsymbol{\omega/c}$ 的关系、精算验证及其物理意义
c语言·开发语言·线性代数·算法·决策树·机器学习·ai科技星
坏柠2 天前
C语言进阶:从零实现一个可靠的环形缓冲区,吃透回绕、边界与并发
java·c语言·算法
choumin2 天前
C程序能调用extern “C“声明的带默认参数的C++函数吗?
c语言·c++·extern c·默认参数
LONGZETECH2 天前
传统实训 vs 仿真实训:从技术架构拆解新能源汽车教学的范式之变
c语言·3d·unity·架构·汽车
白白白小纯2 天前
每日算法day3—回文链表,链表分割
c语言·数据结构·算法·leetcode