申请1G的空间 (是否觉得题目越简单越难做呢)
2015-01-09 13:15
218 查看
曾经碰到过的一个面试题,说,写代码申请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
方法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
相关文章推荐
- 问题 E : 坤哥的难题 (题目本来觉得很难,但是数据很水,居然简单的for就AC)
- HDOJ题目2454 Degree Sequence of Graph G(判断是否是简单图)
- 华为2014机考题目_判断if括号匹配是否合法_堆栈_简单的方法- -
- 简单的介绍一下C中申请的内存空间,free的使用
- Lettcode_9_Palindrome Number ——判断一个数字是否回文(不能申请额外空间)
- 堆内简单申请指定字节数的int型变量的空间并且返回地址
- 【小项目】实现一个简单的对象池,用来管理空间的申请和释放
- poj 2299 Ultra-QuickSort(树状数组+离散化的题目)据说是简单题,不过还是觉得好难。。。
- 腾讯2017年实习生编程题目(第二题)----2.算法基础-字符移位 小Q最近遇到了一个难题:把一个字符串的大写字母放到字符串的后面,各个字符的相对位置不变,且不能申请额外的空间。
- 申请日本空间时用的网站简介
- 1G PHP免费空间
- 一个大企业的考试题,觉得不难也不简单
- 网络存储的新生力军: 1G 空间的box.net
- 暑假经历之ACM培训第七天--做一个简单题目安慰一下
- 申请日本空间全攻略
- 判断输入是否为数字的最简单的方法(用JavaScript的正值表达式)
- 把list倒序排列,不申请空间。
- 申请了个空间
- GMAIL可以让你的硬盘多1G空间-GMail Drive 1.0
- 测试杀毒软件是否有效的最简单和安全的方法