C++ memset 栈空间出现段错误

代码编译运行环境:Ubuntu 64bits+g++(-g -m64),其中 -g 表示生成调试版本,-m64 表示生成 64bits 程序。


1.错误代码

先贴出出错的核心代码:

struct GPU_task_head head;//局部栈空间上的变量
cout<<"sizeof(GPU_task_head):"<<sizeof(GPU_task_head)<<endl;
memset(&head,0,sizeof(GPU_task_head));//运行时出错

以上代码会出现segmentation fault(core dumped),本以为是memset数组越界,导致的段错误,经过仔细检查并不是memset越界导致的。那为什么呢?

先看一下错误代码的输出:
这里写图片描述

再看一下ulimit -a命令列出的系统对shell 启动进程所占用的资源限制,列出结果如下:
这里写图片描述

看图片标红的位置,再对比错误代码的输出的结果中变量的大小,你是否发现了什么!

2.ulimit 命令简介

你是否曾遇到过在程序里面创建线程提示你资源不够,你是否曾遇到过在gcc 中加入 -g 选项,程序崩溃时却没有任何 core 文件产生。如果就,那你就要注意到ulimit命令了。

本次错误也是由于系统对进程资源的限制导致了以上的奇怪的错误结果。memset 栈空间出现段错误是由于系统分每个进程分配的空间不足导致的。

ulimit 通过一些参数选项来管理不同种类的系统资源。这里,我们将讲解这些参数的使用。
ulimit 命令的格式为:ulimit [ options ] [limit]
具体的 options 含义以及简单示例可以参考以下表格。

命令选项含义例子
-a查看全部资源的使用情况ulimit -a 查看全部资源的使用情况
-H设置硬资源描述限制,一旦设置,不能更改ulimit – Hs 64;限制硬资源,线程栈大小为 64K
-S设置软资源限制,一旦设置,可以增加,但是不能超过软资源的限制ulimit – Sn 32;限制软资源,32 个文件描述符。
-ccore文件最大大小,以blocks为单位一般常用ulimit -c unlimited,设置为不限大小
-d设置进程最大数据段的大小,以kbytes为单位ulimit -d unlimited;对进程的数据段大小不进行限制
-f设置进程最大可以创建的文件大小,以blocks为单位ulimit – f 2048;限制进程可以创建的最大文件大小为 2048 blocks
-l最大可加锁内存大小,以 Kbytes 为单位ulimit -l 32;限制最大可加锁内存大小为 32 Kbytes
-m最大内存大小,以 Kbytes 为单位ulimit – m unlimited;对最大内存不进行限制
-n可以打开最大文件描述符的数量ulimit –n128;限制最大可以使用 128 个文件描述符
-p管道缓冲区的大小,以 Kbytes 为单位ulimit – p 512;限制管道缓冲区的大小为 512 Kbytes
-s线程栈大小,以 Kbytes 为单位ulimit – s 512;限制线程栈的大小为 512 Kbyte
-t最大的 CPU 占用时间,以秒为单位ulimit -t unlimited;对最大的 CPU 占用时间不进行限制
-u用户最大可用的进程数ulimit – u 64;限制用户最多可以使用 64 个进程
-v进程最大可用的虚拟内存,以 Kbytes 为单位ulimit -v 200000;限制最大可用的虚拟内存为 200000 Kbytes

3.错误解决办法

错误代码中局部变量 head 的大小占用了 8.7M 的栈空间,已经超过了系统对 Shell 进程栈空间的限制。虽然在定义时没有报错,但是进行memset 置空值却出现了段错误。因此,我们做如下修改:

ulimit – s 81920

将栈空间改为 81M,这样再运行源程序,顺利通过,问题解决。

参考文献

LINUX ulimit命令

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值