C:动态内存分配(2)

在动态内存分配中,比较经典的错误案例如下:

案例 1:

原代码:

void getmemory(char* p)//应改为char** p
{
	p = (char*)malloc(100);//没有把开辟的空间地址传回test函数中的str中
	//应改为*p
}
void test(void)
{
	char* str = NULL;
	getmemory(str);
	strcpy(str, "hello world");//str没有指向有效空间,程序崩溃
	printf(str);
}
int main()
{
	test();
	return 0;
}

本段代码运行会出现崩溃的现象,原因如下:

该程序存在内存泄漏的问题,str以值传递的形式传给p,p为getmemory函数的形参,只在getmemory函数内部有效,当getmemory函数返回之后,动态开辟内存尚未释放,并且无法找到,所以存在内存泄露。

改正1:

void getmemory(char **p)
{
	*p = (char *)malloc(100);
}
void test(void)
{
	char *str = NULL;
	getmemory(&str);
	strcpy(str, "hello world");
	printf(str);
	free(str);
	str = NULL;
}
int main()
{
	test();
	return 0;
}

以传址的方式向getmemory函数传str所指向的值,即为**p,在getmemory函数中以指针*p的形式接受malloc函数开辟的空间;

另外添加了内存释放。

改正2:

char* getmemory(char* p)
{
	p = (char*)malloc(100);
	return p;
}
void test(void)
{
	char* str = NULL;
	str=getmemory(str);
	strcpy(str, "hello world");
	printf(str);
	free(str);
	str = NULL;
}
int main()
{
	test();
	return 0;
}

在getmemory函数中,增加 <return p> 代码来返回开辟的空间地址,则开辟的空间可以在主函数中进行使用,使用完成后进行释放。

案例 2:

原代码:

char* getmemory(void)
{
	char p[] = "hello world";//局部变量,只在此函数内有效
	return p;
}
void test(void)
{
	char* str = NULL;
	str = getmemory();
	printf(str);
}
int main()
{
	test();
	return 0;
}

如代码注释所示,在getmemory函数中定义的变量p为局部变量,无法在其他函数中使用。

相似地:

int* test()
{
	int a = 10;//栈区err
	return &a;
}
int main()
{
	int*p = test();
	return 0;
}

上面这段代码中,test函数中定义的整型变量a为局部变量,在栈区存储,无法用于main函数。

int a = 10;

改正为:

static int a = 10;

这样变量a存储在静态区,可以被main函数所使用。

改正后的完整代码如下:

int* test()
{
	static int a = 10;
	return &a;
}
int main()
{
	int*p = test();
	return 0;
}

相似地:

int* test()
{
	int* ptr = malloc(100);//开辟空间在堆区,不free依然存在,可以传回主函数
	return ptr;
}
int main()
{
	int* p = test();
	return 0;
}

上面代码段的指针变量ptr虽然在test函数内部定义,但static定义其为静态指针变量,存储在静态区,不free依然存在于静态区中,可以在main()函数中进行使用。

案例 3:

原代码:

void getmemory(char** p, int num)
{
	*p = (char*)malloc(num);
}
void test(void)
{
	char* str = NULL;
	getmemory(&str, 100);
	strcpy(str, "hello");
	printf(str);
}
int main()
{
	test();
	return 0;
}

上面本段代码未释放动态开辟的内存,导致内存泄漏。

在使用完动态内存开辟的空间后,增加以下代码用于释放内存空间:

	free(str);//
	str = NULL;//此两行代码可以释放空间

改正后的代码如下:

void getmemory(char** p, int num)
{
	*p = (char*)malloc(num);
}
void test(void)
{
	char* str = NULL;
	getmemory(&str, 100);
	strcpy(str, "hello");
	printf(str);
	free(str);//
	str = NULL;//此两行代码可以释放空间
}
int main()
{
	test();
	return 0;
}

案例 4:

原代码:

void test()
{
	char* str = (char*)malloc(100);
	strcpy(str, "hello");
	free(str);
	if (str != NULL)
	{
		strcpy(str, "world");
		printf(str);
	}
}
int main()
{
	test();
	return 0;
}

以上的free函数把str指向的的内存空间释放,但不会把str置为NULL,所以下面的if判断语句没有意义。

在if语句前面加上

str = NULL;

改正完成后的代码为:

void test()
{
	char* str = (char*)malloc(100);
	strcpy(str, "hello");
	free(str);//此处把str指向的的内存空间释放,并不会把str置为NULL
	str = NULL;

}
int main()
{
	test();
	return 0;
}

案例4很迷,说不明白,我懂就行了。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值