C和指针 第十一章(笔记与习题答案)

第11章

1.为什么使用动态内存分配

声明一个数组的时候,必须使用一个编译时常量指定数组的长度,一般情况我们使用的方法声明一个较大的数组,这种方法的优点是简单。但是它的缺点多:首先引用人为的限制,如果程序需要的元素数量超过了声明的长度,就无法处理。为了避免这个情况的发生,就得把函数声明的大一些,但是这会导致一个恶化,当程序需要的元素数量较少时,矩形数组的大部分内存空间都被浪费了。这种方法还有的缺点是如果输入的数据数量超过了数组的容纳范围,程序必须以一种合理的方式做出响应。

2.malloc函数

malloc的参数就是需要分配的内存字节数。malloc返回一个类型为void*的指针。malloc所返回的内存起始位置将始终能够满足对边界对齐最严格的类型要求。

void *malloc(size_t size);
int *p=(int*)malloc( sizeof (int) * 5 );

3.calloc函数

void *calloc(size_t num_elements,size_element_size);// 分配元素的个数和每个元素的大小
int *p=( int* )calloc( 5, sizeof(int) );

calloc也用于分配内存。
注意:malloc和calloc之间的主要区别是后者在返回指向内存的指针之前把它初始化为0。(如果你的程序只是想把一些值存储到数组中,这个初始化过程纯粹浪费时间)
calloc和malloc之间另一个较小的区别是它们请求内存数量的方式不同。

注意:动态内存分配做常见的错误就是忘记检查所请求的内存是否成功分配。第二大错误来源是操作内存时超出了分配内存的边界,这会引起两种类型的问题,第一种问题显而易见,被访问的内存可能保存了其他变量的值,对它进行修改将会破坏那个变量。第二个问题就不那么明显,在malloc和free的有些实现中,它们以链表的形式维护可用的内存池。对分配的内存之外的区域进行访问可能破化这个链表,这有可能产生异常,从而终止程序。

警告:在使用free函数时,释放一块内存的一部分是不被允许的。动态分配的内存必须整块一起释放。但是realloc函数可以缩小一块动态分配的内存,有效地释放它尾部的部分内存。

4.问题

在这里插入图片描述
答:
2.这将因系统而异。有几个因素可能会影响基于pc的系统上的结果,包括正在使用的内存模型、数据和/或堆栈段中的空间量、系统上可用的内存量,等等。在Unix系统上的结果将取决于可用交换空间的数量以及其他因素。
3.如果输入包含在一个文件中,它肯定是由其他程序(例如编辑器)放在那儿的。如果是这种情况,最长行的长度是由编译器程序支持的,它会做出一个合乎逻辑的选择,确定你的输入缓冲区的大小。
4.alloc 的调用序列与 malloc 相同,与 malloc 不同的是 alloc 在当前的函数的栈帧上分配存储空间,而不是在堆中.这样做的好处是:函数返回时,自动释放它所使用的栈帧,所以不必再为释放空间而费心.也就是说不必要担心操作它的释放问题.同样这样处理的其缺点也很明显:某些系统在函数已被调用后不能增加栈帧长度,于是也就不能支持 alloc 函数.尽管如此,很多软件包还是使用 alloc 函数,也有很多系统支持它.(内存区域可分为栈,堆,静态存储区和常量存储区,对于常见的局部变量,函数形参,临时变量都是在栈上获得内存的,它们的获取方式都是通过编译器直接执行.
而利用指针来管理内存的时候,可以更加自由的像汇编一样处理内存的地址, C 标准函数库提供了很多函数来实现对堆上内存的管理,从开辟内存空间到释放内存空间都有相应的函数)

在这里插入图片描述
5.

  1. 用字面常量作为整型值长度不可取。array=(int )malloc(sizesizeof(int))
    2)从malloc函数返回的值未被检查。如果内存不足,它将是NULL
    3)把指针退到数组左边来调整下标范围或许行得通,但它违背了标准。
    4)指针经过调整之后,第一个元素的下标变成了1,接着for循环从下标0开始,是错误的,会导致程序的崩溃。
    5)数组增值前未检查输入值是为位于合适的范围内。非法的输入值可能会以一种有趣的方式导致程序崩溃。
    6)数组应该返回,而不是被释放。

6.是的,动态分配将使用更少的堆栈空间,因为用于数组的内存将从堆而不是堆栈中获取。只有当被分配的值大于指针的大小时,动态分配标量才会有帮助,大的结构体也是如此。动态分配整数是没有好处的,因为必须跟踪它的指针变量占用的空间与整数本身一样多。
7.程序的内存可能用完,导致后面的内存分配失败。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值