c语言中的小小白-CSDN博客c语言中的小小白关注算法,c++,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm=1001.2014.3001.5343
给大家分享一句我很喜欢我话:
知不足而奋进,望远山而前行!!!
铁铁们,成功的路上必然是孤独且艰难的,但是我们不可以放弃,远山就在前方,但我们能力仍然不足,所有我们更要奋进前行!!!
今天我们更新了动态内存的内容,
🎉 欢迎大家关注🔍点赞👍收藏⭐️留言📝
前言:
下面我们来看一下关于动态内存分配的经典试题,这些都是某些大厂曾经的面试题,希望大家可以好好看好好学,将这些东西通通搞懂它。
经典试题一:
void GetMemory(char* p)
{
p = (char*)malloc(100);
//未进行内存释放free
}
void Test(void)
{
char* str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}
int main()
{
Test();
return 0;
}
我们一起来看一下这道题,乍一看这串代码没有任何问题,但是其实他会内存泄漏和程序崩溃问题
但是我们分析一下就会发现,当我们使用GetMemory进行动态内存分配时,错误就会显现出来了,因为当我们调用结束之后,这个分配到内存也会随之而销毁,所以这块内存就不在了,但是下面我们依然往这块内存里赋值
那我们该如何修改这串代码呢,下面我带大家修改一下。
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;
}
将代码修改成这样,便可以成功进行编译了,既然传数不可以,我们就将地址传过去,这样就可以完美运行了。
经典试题二:
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函数返回之后,使用str指针去访问p数组,就是非法访问,因为p数组的内存已经还给了操作系统。
我们就举个例子吧,一个人叫作张三,然后开了一个宾馆,交了一晚上的钱,然后今天就有了使用权,然后第二天早上退房了,然后第二天下午张三又要去使用这个房间,此时就会被保安给赶出去,这里就相当于非法访问了。也就是返回栈空间地址的问题。
运行之后就会输出:
那么我们应该如何去改一下这串代码呢?
经典试题三:
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进行内存释放,加上这一步就完美了!
经典试题四:
void Test(void)
{
char* str = (char*)malloc(100);
strcpy(str, "hello");
free(str);
if (str != NULL)
{
strcpy(str, "world");
printf(str);
}
}
int main()
{
Test();
return 0;
}
我们来分析一下这串代码,首先将hello赋给str之后,然后就用free进行空间释放了,所以后面的空间就还给操作系统了,虽然他还是存在的,但是我们无法使用了。然后str肯定不等于NIULL,然后将world赋给str,就会覆盖hello,因此会打印world
柔性数组:
下面我们再给大家将一下什么是柔性数组。
什么是柔性数组?
也许你从来没有听过什么是柔性数组这个概念,但是它的的确确是存在的。
在C99中,结构中的最后一个元素允许是未知大小的数组,这就叫做柔性数组的成员。
特点:
结构体中最后一个成员。
最后一个成员是数组,数组大小没有指定
struct S
{
char c;
int n;
int arr[0]/arr[];//柔性数组。
};
柔性数组的特点:
1.结构体中的柔性数组成员前面必须至少又一个成员
2.sizeof返回的这种结构大小不包括柔性数组的内存
3.包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。
柔性数组的使用:
struct S
{
char c;
int n;
int arr[0];//柔性数组。
};
int main()
{
struct S* ps = (struct S*)malloc(sizeof(struct S) + 5 * sizeof(int));
return 0;
}
这就是一个柔性数组的例子,其实就是可以是数组的大小可以变大变小。
总结:
本篇博客我们讲了关于柔性数组与动态内存分配的一些例题,希望对大家有一定的帮助!
我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=1gi91bbmli47u