前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >动态内存经典笔试题分析及柔性数组

动态内存经典笔试题分析及柔性数组

作者头像
用户11036582
发布2024-03-21 18:41:59
580
发布2024-03-21 18:41:59
举报

给大家分享一句我很喜欢我话: 知不足而奋进,望远山而前行!!! 铁铁们,成功的路上必然是孤独且艰难的,但是我们不可以放弃,远山就在前方,但我们能力仍然不足,所有我们更要奋进前行!!! 今天我们更新了动态内存的内容

前言:

下面我们来看一下关于动态内存分配的经典试题,这些都是某些大厂曾经的面试题,希望大家可以好好看好好学,将这些东西通通搞懂它。

经典试题一:

代码语言:javascript
复制
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进行动态内存分配时,错误就会显现出来了,因为当我们调用结束之后,这个分配到内存也会随之而销毁,所以这块内存就不在了,但是下面我们依然往这块内存里赋值

那我们该如何修改这串代码呢,下面我带大家修改一下。

代码语言:javascript
复制
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;
}

将代码修改成这样,便可以成功进行编译了,既然传数不可以,我们就将地址传过去,这样就可以完美运行了。

经典试题二:

代码语言:javascript
复制
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数组的内存已经还给了操作系统。

我们就举个例子吧,一个人叫作张三,然后开了一个宾馆,交了一晚上的钱,然后今天就有了使用权,然后第二天早上退房了,然后第二天下午张三又要去使用这个房间,此时就会被保安给赶出去,这里就相当于非法访问了。也就是返回栈空间地址的问题。

运行之后就会输出:

那么我们应该如何去改一下这串代码呢?

经典试题三:

代码语言:javascript
复制
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进行内存释放,加上这一步就完美了!

经典试题四:

代码语言:javascript
复制
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中,结构中的最后一个元素允许是未知大小的数组,这就叫做柔性数组的成员。

特点: 结构体中最后一个成员。 最后一个成员是数组,数组大小没有指定

代码语言:javascript
复制
struct S
{
	char c;
	int n;
	int arr[0]/arr[];//柔性数组。
};

柔性数组的特点:

1.结构体中的柔性数组成员前面必须至少又一个成员 2.sizeof返回的这种结构大小不包括柔性数组的内存 3.包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。

柔性数组的使用:

代码语言:javascript
复制
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;
}

这就是一个柔性数组的例子,其实就是可以是数组的大小可以变大变小。

总结:

本篇博客我们讲了关于柔性数组与动态内存分配的一些例题,希望对大家有一定的帮助!

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-03-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言:
  • 经典试题一:
  • 经典试题二:
  • 经典试题三:
  • 经典试题四:
  • 柔性数组:
    • 什么是柔性数组?
      • 柔性数组的特点:
        • 柔性数组的使用:
        • 总结:
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档