申请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


0 0
原创粉丝点击