免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: mgqw
打印 上一主题 下一主题

如何判断申请很大数组是否成功? [复制链接]

论坛徽章:
0
11 [报告]
发表于 2010-06-03 15:26 |只看该作者
回复 9# wwdwwd


    朋友,问题出在这里:printf("%d\n",a[0]);,申请失败了,是NULL,你怎么能打印呢?

论坛徽章:
0
12 [报告]
发表于 2010-06-03 16:11 |只看该作者
错了就是错了,为啥这么要面子呢。
c/unix 发表于 2010-06-03 15:23

我知道是怎么回事了,下面的printf导致的段错误,多谢指正!

论坛徽章:
0
13 [报告]
发表于 2010-06-03 16:12 |只看该作者
回复  wwdwwd


    朋友,问题出在这里:printf("%d\n",a[0]);,申请失败了,是NULL,你怎么能打印呢? ...
rain_fish 发表于 2010-06-03 15:26

嗯,对,忘了判断了。

论坛徽章:
0
14 [报告]
发表于 2010-06-03 16:26 |只看该作者
cugb_cat兄,不好意思,刚才是我测试的问题。我刚才发现另外一个问题:如果malloc失败后继续使用,会导致段错误,但这时的段错误能用信号捕捉到;如果是栈上分配错误时后使用导致的段错误则捕获不到。
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <signal.h>

  4. void signal_handler(int signo) {
  5.         printf("get signal %d\n",signo);
  6. }

  7. void test(void) {
  8.         unsigned int  a[100000000];
  9.         printf("%d\n",a[0]);
  10. }
  11. int main()
  12. {
  13.     struct sigaction act;
  14.     sigemptyset(&act.sa_mask);
  15.     act.sa_handler = signal_handler;
  16.     sigaction(SIGSEGV, &act, NULL);
  17.     test();
  18.     return 0;
  19. }
复制代码
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <signal.h>

  4. void signal_handler(int signo) {
  5.         printf("get signal %d\n",signo);
  6. }

  7. void test(void) {
  8.         int  *a = malloc(1000000000);
  9.         printf("%d\n",a[0]);
  10. }
  11. int main()
  12. {
  13.     struct sigaction act;
  14.     sigemptyset(&act.sa_mask);
  15.     act.sa_handler = signal_handler;
  16.     sigaction(SIGSEGV, &act, NULL);
  17.         test();
  18.         return 0;
  19. }
复制代码

论坛徽章:
0
15 [报告]
发表于 2010-06-03 17:03 |只看该作者
好高深啊

论坛徽章:
0
16 [报告]
发表于 2010-06-03 18:37 |只看该作者
cugb_cat兄,不好意思,刚才是我测试的问题。我刚才发现另外一个问题:如果malloc失败后继续使用,会导致段 ...
wwdwwd 发表于 2010-06-03 16:26



发之前自己先好好想想啊,堆上分配为什么会段错误?
是因为malloc失败,返回指针是NULL,你打印a[0]就是操作空指针,你捕捉的信号是操作空指针的硬件信号
你改成在栈上分配,失败后a是一个随机值,很可能不是NULL或者其他禁止访问的内存,你打印a[0]当然有可能没问题了

论坛徽章:
0
17 [报告]
发表于 2010-06-03 19:06 |只看该作者
cugb_cat兄,不好意思,刚才是我测试的问题。我刚才发现另外一个问题:如果malloc失败后继续使用,会导致段 ...
wwdwwd 发表于 2010-06-03 16:26


http://www.linux-ask.com/Linux%B1%E0%B3%CC%CE%CA%CC%E2/4672.html
这篇文章应该可以帮到你
因为信号处理函数的上下文与进程栈的上下文是同一个,即使用相同的ebp和esp,当把栈空间耗尽时,已经没有栈空间可以供信号处理函数使用了,所以,就无法对捕捉到的SIGSEGV信号做出处理了。
如果是堆溢出导致的SIGSEGV,是可以通过捕捉该信号来做善后处理的,但如果是由于函数递归次数太多,导致的SIGSEGV,则是无法进行善后了。
或许可以通过使用守护线程,将被守护的线程的esp强制往回移动,以跳出无尽的递归,但这个方法尚不知是否可用,因为我还不清楚保存线程上下文的内存是属于核态还是用户态,如果是核态,则无能为力了。
还有一种方式,就是通过堆空间来将栈增大,提供非常的栈空间,但这样尚不能彻底解决无穷递归导致的栈耗尽,毕竟再大都是有限的。

论坛徽章:
0
18 [报告]
发表于 2010-06-04 12:36 |只看该作者
目前还是没有发现比检查malloc返回是否为NULL更好的办法{:3_190:}{:3_190:}{:3_190:}

论坛徽章:
0
19 [报告]
发表于 2010-06-04 13:54 |只看该作者
好像还是没有回答楼主的问题,malloc 申请可以判断有没有出错,但是char AA[10000000000000000000000000000000000000000000000]这样的怎么判断呢?

论坛徽章:
0
20 [报告]
发表于 2010-06-04 14:09 |只看该作者
好像还是没有回答楼主的问题,malloc 申请可以判断有没有出错,但是char AA[10000000000000000000000000000 ...
yikaikai 发表于 2010-06-04 13:54


这个判断不了,因为这个是在编译时就确定了的,如果是在栈上,则为该数组分配栈空间时,才会出错,即调用定义该数组的函数时,而且捕捉不到SIGSEGV信号,原因我前面已经说了,如果是全局变量,程序一启动就会出错了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP