LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   Segmentation fault (http://www.linuxquestions.org/questions/programming-9/segmentation-fault-672145/)

Sparcler 09-24-2008 05:10 PM

Segmentation fault
 
Hello, I find myself faced with an interesting problem, and I don't know where to turn. I'm not sure whether it is a compiler problem or a kernel problem. I'm trying to write a program in c++ using g++. the code compiles just fine but when I try to run it it I get a segmentation fault. It is a simple program, it declares a 3 dimensional array of type int and then fills the array. As far as I can tell there isn't any problems with the code, but I have included it along with my makefile.
makefile
CC=g++
CFLAGS=-Wall
math: math.o
$(CC) $(CFLAGS) -o math math.o
math.o: math.cpp
$(CC) $(CFLAGS) -c math.cpp
clean:
rm ./*.o
rm ./math
math.cpp
#include<iostream>

using namespace std;

int main(int argc, char *argv[]){
int test=0;
const int xSize=1024, ySize=768, depth=3;
int graphic[ySize][xSize][depth];

for(int i=0;i<ySize;i++){
for(int j=0;j<xSize;j++){
graphic[i][j][0]=i;
graphic[i][j][1]=j;
graphic[i][j][2]=i+j;
}
}

return test;
}
I think the problem is with the array size, if I declare it as 800x600x3 there is no problem, but when I go to 1024x768x3 or larger it will seg fault every time. Here is the question dose the Linux kernel impose a limitation on application memory usage, or is there a compiler flag that I need to use to allow the larger memory allocation, or do I have a bug in my code?

mjmwired 09-24-2008 05:25 PM

Curious, what does the debugger output say?
Compile with '-g' flag and use 'gdb':
# gdb math

paulsm4 09-24-2008 05:52 PM

Also, you seem to have "xSize" and "ySize" reversed - either in your loop, or in your declaration - the two don't match each other.

PS:
It's not a compiler problem, nor a kernel problem. I think this is an example of "PEBKAM"...

fantas 09-24-2008 05:58 PM

My guess is that it's a limit of how much memory you can allocate on the stack, but I have no figues here. I would try to allocate the array on the heap instead.

Sparcler 09-24-2008 06:12 PM

After more testing I think the problem is with the kernel. It appears that the kernel limits the amount of memory that a process can use. So my question now becomes what is the limit and is there a way around it?

David1357 09-24-2008 06:35 PM

Quote:

Originally Posted by Sparcler (Post 3290764)
I think the problem is with the array size, if I declare it as 800x600x3 there is no problem, but when I go to 1024x768x3 or larger it will seg fault every time. Here is the question dose the Linux kernel impose a limitation on application memory usage, or is there a compiler flag that I need to use to allow the larger memory allocation, or do I have a bug in my code?

Code:

800 x 600 x 3 x sizeof(int) =  576,000 bytes = 562 K
1024 x 768 x 3 x sizeof(int) = 9,437,184 bytes =  9 M

What does "ulimit -d" say?

paulsm4 09-24-2008 09:36 PM

Hi -

When you said "operating system" and "compiler", I thought you were implying some Linux bug or GCC bug might be the culprit. That's definitely not the case here ;-)

You're absolutely correct about the stack overflow issue. It dies on Windows (Visual C++) too. As David1357 pointed out, you need 9,437,184 bytes of stack, but Windows processes have a default stack limit of 1MB (Linux processes about 8MB).

In Windows, you can change the limit by compiling with /STACKSIZE 1048576 (for 10MB). This alters the .exe, instructing the OS to reserve 10MB stack for the process.

In Linux, you should be able to change this with "ulimit -s".

You can also circumvent the problem (on both Linux and Windows) by:
1) static allocation (use "static", or declare the array outside of a function)
2) heap allocation (use C "malloc()" or C++ "new")

Here are a couple of links:
http://cs.nyu.edu/exact/core/doc/stackOverflow.txt
http://bytes.com/forum/thread221976.html

Sparcler 09-24-2008 09:59 PM

Thanks for the ideas, I decided to change things, The arrays get to big too fast.

ErV 09-25-2008 12:39 AM

Quote:

Originally Posted by fantas (Post 3290800)
My guess is that it's a limit of how much memory you can allocate on the stack, but I have no figues here. I would try to allocate the array on the heap instead.

IT was said in OpenDynamic Engine documentation that Linux/Unix are one of few several OSes that can increase stack size dynamically. This is information might be incorrect, but ODe uses (or used) alloca (allocates memory on stack) a lot, and still works.


Quote:

Originally Posted by Sparcler (Post 3290813)
It appears that the kernel limits the amount of memory that a process can use.

I don't think so. 1024x768x3 is small amount of memory (although it might depend on how you allocate it). You should debug your program with gdb instead of making any assumptions.

johnsfine 09-25-2008 08:12 AM

Quote:

Originally Posted by David1357 (Post 3290831)
Code:

800 x 600 x 3 x sizeof(int) =  576,000 bytes = 562 K
1024 x 768 x 3 x sizeof(int) = 9,437,184 bytes =  9 M


There's a significant little typo in the above.
Code:

800 x 600 x 3 x sizeof(int) = 5,760,000 bytes = 5625 K
1024 x 768 x 3 x sizeof(int) = 9,437,184 bytes = 9216 K = 9 M

But for figuring out whether the array would fit on an 8MB stack, the typo didn't matter.

fantas 09-25-2008 09:33 AM

Quote:

Originally Posted by ErV (Post 3290996)
IT was said in OpenDynamic Engine documentation that Linux/Unix are one of few several OSes that can increase stack size dynamically. This is information might be incorrect, but ODe uses (or used) alloca (allocates memory on stack) a lot, and still works.

This could also just mean that they wanted to point out that you can also call setrlimit from a running process, which AFAIK is not possible under Windows for example. And not that it's somehow automatically done by the system when reaching the current limit for the particular process (as how I understood your interpretation).

David1357 09-25-2008 11:07 AM

Quote:

Originally Posted by johnsfine (Post 3291322)
There's a significant little typo in the above.

Argh. This HP 50g (which cost way too much) does not give the proper key feedback. I must have entered "80 600 3 4" or "800 60 3 4". May God bless the person who stole my 48SX.

ErV 09-25-2008 11:29 AM

Quote:

Originally Posted by fantas (Post 3291427)
This could also just mean that they wanted to point out that you can also call setrlimit from a running process, which AFAIK is not possible under Windows for example. And not that it's somehow automatically done by the system when reaching the current limit for the particular process (as how I understood your interpretation).

Explanation.
Complex ODE simulation requires huge stack segment. Up to 70 megabytes, or more. Or it was that way in in ODE 0.35 or something. This is because within many functions they allocate huge arrays, tables (matrices, etc) with "alloca". On windows such application quickly dies with "stack overflow", unless stack size was specified during compilation. On linux it works (or they say so). This was explained in ODE documentation or FAQ somewhere (they said that Linux/Unix OS enlarges stack when necessary), but I was working with all that several years ago, so I don't remember where exactly was that, and situation may have changed. I cannot say anything setrlimit, because I'm unfamiliar with it - I always try to use cross-platform API instead of OS-specific function calls. See ode-related documentation for more details, if you are interested.

paulsm4 09-25-2008 12:25 PM

Erv -
read this:

fantas 09-26-2008 03:47 AM

Quote:

Originally Posted by ErV (Post 3291534)
Explanation.
Complex ODE simulation requires huge stack segment. Up to 70 megabytes, or more. Or it was that way in in ODE 0.35 or something. This is because within many functions they allocate huge arrays, tables (matrices, etc) with "alloca". On windows such application quickly dies with "stack overflow", unless stack size was specified during compilation. On linux it works (or they say so). This was explained in ODE documentation or FAQ somewhere (they said that Linux/Unix OS enlarges stack when necessary), but I was working with all that several years ago, so I don't remember where exactly was that, and situation may have changed. I cannot say anything setrlimit, because I'm unfamiliar with it - I always try to use cross-platform API instead of OS-specific function calls. See ode-related documentation for more details, if you are interested.

Thanks ErV. I've been reading through the FAQ and it is there indeed, but does seem to be simple misinformation. Not in a meant-in-a-bad-way, but rather in a we-have-no-other-explanation kind of way. The real reason behind it is probably simply that the default stack sizes are different between WIN32 and Unix (1MB versus 8MB), and this can make a world of a difference when allocating huge data sets.


All times are GMT -5. The time now is 02:01 PM.