申请1G的空间 (是否觉得题目越简单越难做呢)
来源:互联网 发布:2014年网络热词 编辑:程序博客网 时间:2024/06/10 10:27
曾经碰到过的一个面试题,说,写代码申请1G的空间吧!
方法1:直接定义
char *buffer[1024*1024*1024];
解析:这就是一个1G的空间了,可是问题是,这种申请方式是在栈区开辟的,栈区往往没有那么大,比如linux中可使用 ulimit -s 查看栈区的限制大小,单位是KB,默认是8MB或者10MB的样子。所以这种方式的申请方法在不改 ulimit -s 的值的情况下,程序在初始化包含定义这个变量的函数的时候就会死掉,也就是段错误,原因是,栈区由系统管理的,系统将包含该定义的子函数放入栈区的时候,由于栈空间不足就挂掉了。修改栈大小的方法是 ulimit -s 1049600。也就是改栈区大小为1G零1M,当然应该再大一点,不能刚刚好(程序运行过程中不单单装着一个变量,还有其他东东)。
结果:
修改ulimit -s 之前
编译:通过
运行:段错误
修改ulimit -s 之后
编译:通过
运行:通过
扩展:
1)修改大小为1024*1024*1024*2
编译:不通过
报警告:integer overflow in expression 整型溢出
报错误:overflow in constant expression 常量表达式溢出
报错误:size of array is negative 数组大小为负值
原因分析:int的最大值是2^32-1,1024*1024*1024*2刚好越界,也就是 -2147483648,刚好解释第二个数组大小不能为负的报错, 是否在想给这个值减一就可以了呢,其实还是编译报错--常量表达式溢出,毕竟乘法优先级高,计算过程中会产生溢出,也就报错了,即使,1024*1024*1024*2溢出后是 -2147483648,减一变为 2147483647 最终值合法,可是那么一瞬间溢出了,编译不通过了。
2)修改大小为1024*1024*1024*4
编译:不通过
报警告:integer overflow in expression 整型溢出
报错误:overflow in constant expression 常量表达式溢出
报错误:overflow in array dimension 数组维数溢出
原因解析:此处发现有一个不同的错误,数组维数溢出,经过以%ld和%d的方式打印出该值,发现其实是0,那么考虑是不能定义大小为0的数组,其实可以定义。该错误原因尚不明确,但是当把1024*1024*1024*4 改为 1024*1024*1024*4l (末尾加L,含义是long类型)程序编译可通过了,运行段错误是因为栈小了呗,ulimit改之,编译运行都通过,于是会发现,该方法申请的空间受ulimit -s限制的同时,long类型的大小都支持了(long八字节,2^64-1),还有多大空间不能申请呢。
chu
结论:显然,没有问题的方式!但是栈区还是很有限的,在不知道修改ulimit的情况下,编译通过,运行段错误是不是会懵了呢,相比找原因得找半天才对。
方法2:malloc堆区开辟
char *buffer;
buffer = (char *)malloc(1024*1024*1024);
if ( NULL == buffer )
fprintf(stderr,"malloc fail. ErrNo[%d],ErrMsg[%s]\n",errno,strerror(errno));
else
fprintf(stdout,"malloc ok\n");
解析:这种方式,编译运行,一路无误
扩展:
1)如果将大小改为1024*1024*1024*2,
编译:通过
报警告:integer overflow in expression 整型溢出
运行出失败:malloc fail. ErrNo[12],ErrMsg[Cannot allocate memory]
原因分析malloc接受的参数是size_t,size_t是标准C库中定义的,应为unsigned int,在64位系统中为 long unsigned int,我测试环境是64位linux,所以改为1024*1024*1024*2l 多加一个L,代表是long类型,编译无警告,运行可通过
2)如果大小改为1024*1024*1024*2-1,
编译:通过
报警告:integer overflow in expression 整型溢出
运行:通过
原因分析1024*1024*1024*2刚好溢出int,最终值便是int的最小值 -2147483648 ,减一后变为int的最大值 2147483647,于是是malloc可用的合法值,所以malloc成功,之所以有警告应该是因为乘法的优先级高,在那么一瞬间真的发生了溢出。
结论:就应该malloc申请,但是不能忘了free,同时申请空间大于等于2G时别忘了加L,因为默认的常量值是int型
方法三、定义结构体然后new
1)定义结构体,或者说定义类
2)用new生成对象,
3)别忘了free
4)真的怕忘了free,那就用智能指针,shared_ptr
5)智能指针的好处在于不用free,系统会自动回收,具体请看其他文章。如:http://blog.csdn.net/u011866460/article/details/42027457
- 申请1G的空间 (是否觉得题目越简单越难做呢)
- G(1945): 最简单的题目
- 觉得有用的面试题目
- HDOJ题目2454 Degree Sequence of Graph G(判断是否是简单图)
- 家科技开发时间空间按时交付经济案件是否觉得
- JAVA面试题--觉得有意思的题目
- 水仙花数,之前觉得不简单的题目
- 简单的题目1
- oracle 10g数据文件的表空间简单扩展
- poj 2299 Ultra-QuickSort(树状数组+离散化的题目)据说是简单题,不过还是觉得好难。。。
- 【小项目】实现一个简单的对象池,用来管理空间的申请和释放
- 堆内简单申请指定字节数的int型变量的空间并且返回地址
- 申请空间
- 今天新申请的空间,欢迎光临!
- 指针空间的申请和释放
- 指针空间的申请和释放(C)
- 申请堆空间时出现的错误
- 二维空间的申请和释放(转)
- StageFright框架(五)Video Rendering
- 成人癫痫病好治吗
- delphi产生GUID
- android中获取SharedPreference对象的二种方法
- eclipse 编辑器代码间距格式化
- 申请1G的空间 (是否觉得题目越简单越难做呢)
- 与Android手机交互:fastboot 协议 和 adb 协议
- StageFright框架(六)Audio Playback的流程
- yii 计划任务
- makefile全面总结
- 广告活动新模式--手机应用推广和微信关注
- 哪有专业治癫痫
- StageFright框架(七)Audio和Video的同步
- 完整java开发中JDBC连接数据库代码和步骤