社区
Linux/Unix社区
帖子详情
用gcc编译时如何增加默认栈的大小啊?
ganghust
2006-06-06 06:54:56
目前我的一个程序老师出现段错误,中间有很多递归操作,现在估计是默认栈太小了,希
望能够增加栈的大小,不知道编译选现如何设置,希望大侠指点:)
...全文
4237
20
打赏
收藏
用gcc编译时如何增加默认栈的大小啊?
目前我的一个程序老师出现段错误,中间有很多递归操作,现在估计是默认栈太小了,希 望能够增加栈的大小,不知道编译选现如何设置,希望大侠指点:)
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
20 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
HoBoss
2006-11-25
打赏
举报
回复
mark
lxzhou
2006-11-25
打赏
举报
回复
突然间才发现差距之大, 看来大学剩下来还有很多事要做。谢谢
koolfool
2006-11-25
打赏
举报
回复
我在FC3,gcc3.4.2环境下进行该实验,证明线程的栈确实有固定大小,也就是ulimit -a显示的那个值,在我的实验室环境下为10M字节
实验1:
#include <stdio.h>
#include <pthread.h>
int i = 0;
void *test(void * s) {
int buffer[1024];
printf("i=%d\n", i);
i++;
test(s);
}
int main() {
pthread_t p;
pthread_create(&p, NULL, &test, NULL);
sleep(100);
}
并且可以使用如下代码修改这个线程栈的大小为16M:
实验2:
#include <stdio.h>
#include <pthread.h>
int i = 0;
void *test(void * s) {
int buffer[1024];
printf("i=%d\n", i);
i++;
test(s);
}
int main() {
pthread_t p;
pthread_attr_t tattr;
void *stack;
pthread_attr_init(&tattr);
stack=malloc(16*1024*1024);
pthread_attr_setstack(&tattr,stack,16*1024*1024); //注意这个空间应该从堆中分配,如果从栈中分配,就会出现另一个问题,我们后面会提到
pthread_create(&p, &tattr, &test, NULL);
sleep(100);
}
但是如果用两个线程使用默认大小,来进行上面的实验,两个栈的总和并不是一个线程的二倍,并且这个总和也不是固定值
实验3:
#include <stdio.h>
#include <pthread.h>
int i = 0;
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
void *test(void * s) {
int buffer[1024];
pthread_mutex_lock(&mutex);
printf("i=%d\n", i);
i++;
pthread_mutex_unlock(&mutex);
test(s);
}
int main() {
pthread_t p1,p2;
pthread_create(&p1, NULL, &test, NULL);
pthread_create(&p2, NULL, test, NULL);
sleep(100);
}
如果不使用任何线程的话,那么一个进程的栈也不是理论上的2G,而是比一个线程的栈稍(ulimit -a 的值10M)大一些,并且这个栈的大小也不总是固定的
实验4:
#include <stdio.h>
int i=0;
void fun()
{
int buffer[1024];
printf("i=%d\n",i);
i++;
fun();
}
int main()
{
fun();
sleep(100);
}
如果pthread_attr_setstack设置的线程栈是从栈空间分配的话,如果线程栈的大小为10M的话,那么线程栈的大小也不是固定不变了而是和实验4的结果相同(类似?)
如果线程栈大小为11M的话,那么线程栈的大小也不是固定不变,但这个时候有可能在进程一开始的时候就发生段错误,即使是同一个可执行文件多次不同执行也会出现这种现象,说明这个栈的大小是和gcc的编译与链接无关的
实验5:
#include <stdio.h>
#include <pthread.h>
int i = 0;
void *test(void * s) {
int buffer[1024];
printf("i=%d\n", i);
i++;
test(s);
}
int main() {
pthread_t p;
pthread_attr_t tattr;
char stack[11*1024*1024];
pthread_attr_init(&tattr);
pthread_attr_setstack(&tattr,&stack[0],11*1024*1024);
pthread_create(&p, &tattr, &test, NULL);
sleep(100);
}
结论:
1. 进程的栈大小是在进程执行的时刻才能指定的,即不是在编译的时刻决定,也不是链接的时刻决定,否则就不会有实验5的结果
2. 进程的栈大小是随机确定的至少比线程的栈要大,但是不到线程栈大小的2倍
3. 线程栈的大小是固定的,也就是ulimit -a显示的值
无知者无谓
2006-11-24
打赏
举报
回复
同意1楼
hyg2008
2006-11-24
打赏
举报
回复
mark
starstargao
2006-11-24
打赏
举报
回复
the size of linux kernel stack is 8K , users' is 8M
this is the data of rehat 9 default
overearth
2006-08-24
打赏
举报
回复
Visual C++可以在链接的指定,gcc 的用法我也一直在找..
nwcow
2006-08-24
打赏
举报
回复
ld用--stack reserved,commit
liu584
2006-08-24
打赏
举报
回复
关注
beepbug
2006-06-15
打赏
举报
回复
在IA-32(32位Intel芯片)里,进程的虚拟空间是4GB。其中包括进程头、正文段、数据段、栈空间,剩下的留作堆空间,用于动态分配。栈空间是在进程生成时,由系统一次性分配的,不太可能有2GB大。
栈空间有一个默认大小,可以在编译时,由某个链接开关(哪个忘了,LZ可以翻翻GCC资料)改变大小。因此,确切地说,是在链接时确定的。
--------------------------
我的BLOG:http://blog.csdn.net/beepbug/
x86
2006-06-07
打赏
举报
回复
把测试代码改成下面这样可以确定线程的栈确实有2M的限制:
#include <stdio.h>
#include <pthread.h>
int i = 0;
void *test(void * s) {
int buffer[1024];
printf("i=%d\n", i);
i++;
test(s);
}
int main() {
pthread_t p;
pthread_create(&p, NULL, &test, NULL);
sleep(100);
}
x86
2006-06-07
打赏
举报
回复
线程的栈似乎有一定限制,这个可以做实验来确认一下。
x86
2006-06-07
打赏
举报
回复
首先你需要运行
ulimit -a
看一下stack是否被限制,如果是unlimited,那么栈的大小只受内存大小限制,当然还有一个2G的上限。至于是否能达到2G上限,答案是否定的,因为除了栈,程序还有别的地方会用到内存。不过linux在某种方式下可以用到最高64G的内存,不知道栈是否也可以突破2G的限制。
给你给小程序来测试栈的限制,
先用ulimit -s 1024设置stack限制为1024k,运行下面的程序会发现i=252的时候会段错误,此时栈大概用了252*(4k+x),差不多是1024k,其中的x是每次递归的开销,包括函数调用地址压栈,4k是每次递归的数组(局部变量)占用栈的大小。
如果栈的限制是unlimited,仔细看一下你的代码,也许是其他问题导致段错误,因为递归一般不会引起栈不够,除非你的程序逻辑有问题造成无限制递归。
#include <stdio.h>
int i = 0;
void test() {
int buffer[1024];
printf("i=%d\n", i);
i++;
test();
}
int main() {
test();
}
xiangding
2006-06-07
打赏
举报
回复
楼上的,在window中,栈的大小就是在编译中指定的,难道linux不一样吗?
liumangxiong(陈世奎): 栈可以达到2G? 错了吧,如果是一个线程里面?栈好像只有2M而已吧。
linaxing
2006-06-07
打赏
举报
回复
栈的大小不是编译时决定的,所以不能在编译时增加它的大小。
可以用setrlimit()来增加栈的大小。
ganghust
2006-06-07
打赏
举报
回复
谢谢了。我这个程序是从x86移植到powerpc上的,使用List操作的地方老有问题。
linaxing
2006-06-07
打赏
举报
回复
to: xiangding(一蓑烟雨任平生!)
让你给说中了,linux下确实不一样,linux下的可执行文件不会像windows下的一样将栈的大小记录到可执行文件中,所以你不能在gcc中指定栈的大小!
NNBWOLF
2006-06-07
打赏
举报
回复
学习
zengwh
2006-06-07
打赏
举报
回复
gdb ***
bt
默默努力的小熊
2006-06-06
打赏
举报
回复
一般情况下是不会出现栈太小的,因为用户空间中栈可以有2G多的空间。仔细检查一下指针的使用吧,是不是使用了未初始化的指针了?最直接的办法,就是用GDB跟踪到出错的地方,那就知道究竟是什么出错了。
不同平台下对
默认
栈
大小
修改
在应用程序我们经常需要定义大的数组,数组定义成局部变量非静态变量,那么数组就会在
栈
上分配,当数组超过
默认
栈
的
大小
时,会引起非常内存访问。 一般,在Unix-like平台,
栈
的
大小
不是由程序自己来控制的而是由...
GCC
编译
程序如何减少堆
栈
空间的
大小
?
3.
默认
栈
空间
大小
可设置,总的来说这个问题更多在于避免
栈
溢出,因为大多数程序可能因为输入有不确定的运行行为,因此大多数时候
栈
空间只能靠估计,通过避免使用过大的局部变量,避免递归深度过深可以减少
栈
空间的...
在不同平台修改
默认
栈
大小
在应用程序我们经常需要定义大的数组,数组定义成局部变量非静态变量,那么数组就会在
栈
上分配,当数组超过
默认
栈
的
大小
时,会引起非常内存访问。那么如何修改系统
默认
的
栈
的
大小
呢。 一般,在Unix-like平台,
栈
的...
gcc
编译
优化选项
因此,无论是
GCC
还是Clang,只要使用了相应的指令集优化标志...-Os选项专门针对目标文件
大小
进行优化,执行所有不
增加
目标文件
大小
的-O2优化选项,并执行专门减小目标文件
大小
的优化选项。-O0表示无优化,是
默认
选项。
简明Linux-Linux下
GCC
编译
C程序(g++
编译
c++类似)
GCC
编译
步骤简介1
GCC
编译
四步骤2
GCC
编译
选项3 静态库和共享库3.1 静态库生成及使用3.2 动态库生成及使用3.3**数据段合并和地址回填**1.4 注意事项 1
GCC
编译
四步骤
GCC
编译
可执行程序四步骤:预处理
编译
汇编 ...
Linux/Unix社区
23,125
社区成员
74,509
社区内容
发帖
与我相关
我的任务
Linux/Unix社区
Linux/Unix社区 应用程序开发区
复制链接
扫一扫
分享
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章