开发者

Memory allocation for a matrix in C

Why is the following code resulting in Segmentation fault? (I'm trying to create two matrices of the same size, one with static and the other with dynamic allocation)

#include <stdio.h>
#include <stdlib.h>

//Segmentation fault!
int main(){
    #define X 5000
    #define Y 6000

    int i;
    int a[X][Y];

    int** b = (int**) malloc(sizeof(int*) * X);
    for(i=0; i<X; i++){
        b[i] = malloc (sizeof(int) * Y);
    }
}

Weirdly enough, if I comment out one of the matrix definitions, the code runs fine. Like this:

#include <stdio.h>
#include <stdlib.h>

//No Segmentation fault!
int main(){
    #define X 5000
    #define Y 6000

    int i;
    //int a[X][Y];

    int** b = (int**) malloc(sizeof(int*) * X);
    for(i=0; i<X; i++){
        b[i] = malloc (sizeof(int) * Y);
    }
}

or

#include <stdio.h>
#include <stdlib.h>

//No Segmentation fault!
int main(){
    #define X 5000
    #define Y 6000

    int i;
    int a[X][Y];

    //int** b = (int**) malloc(sizeof(int*) * X);
    //for(i=0; i<X; i++){
    //  b[i] = malloc (sizeof(int) * Y);
    //}
}

I'm running gcc on Linux on a 32-bit machine.

Edit: Checking if malloc() succeeds:

#include <stdio.h>
#include <stdlib.h>

//No Segmentation fault!
int main(){
    #define X 5000
    #define Y 6000

    int i;
    int a[X][Y];

    int* tmp;
    int** b = (int**) malloc(sizeof(int*) * X);
    if(!b){
        printf("Error on first malloc.\n");
    }
    else{
        for(i=0; i<X; i++){          
            tmp = malloc (sizeof(int) * Y);
            if(tmp)
               b[i] = tmp;
            else{
               printf("Error on second malloc, i=%d.\n", i);
               return;
            }
        }
    }    
}

Nothing is printed out when I run it (expec开发者_如何学编程t of course for "Segmentation fault")


Your a variable requires, on a 32-bit system, 5000 * 6000 * 4 = 120 MB of stack space. It's possible that this violates some limit, which causes the segmentation fault.

Also, it's of course possible that malloc() fails at some point, which might casue you to dereference a NULL pointer.


You are getting a segmentation fault which means that your program is attempting to access a memory address that has not been assigned to its process. The array a is a local variable and thus allocated memory from the stack. As unwind pointed out a requires 120 Mbytes of storage. This is almost certainly larger than the stack space that the OS has allocated to your process. As soon as the for loop walks off the end of the stack you get a segmentation fault.

In Linux the stack size is controlled by the OS not the compiler so try the following:-

$ ulimit -a

In the response you should see a line something like this:-

stack size (kbytes)            (-s)  10240

This means that each process gets 10Mbyte of storage, nowhere near enough for your large array.

You can adjust the stack size with a ulimit -s <stack size> command but I suspect it will not allow you to select a 120Mbyte stack size!

The simplest solution is to make a a global variable instead of an local variable.


Try to increase heap and stack limits in GCC:

gcc -Wl,--stack=xxxxx -Wl,--heap=yyyyy


Those are sizable allocations. Have you tried checking to make sure malloc() succeeds?

You might use malloc() for all your arrays, and check to make sure it succeeds each time.


A stack overflow (how appropriate!) can result in a segmentation fault which is what it seems you're seeing here.

In your third case the stack pointer is being moved to an invalid address but isn't being used for anything since the program then exits. If you put any operation after the stack allocation you should get a segfault.


Perhaps the compiler is just changing the stack pointer to some large value but never using it, and thus never causing a memory access violation.

Try initializing all of the elements of A in your third example? Your first example tries to allocate B after A on the stack, and accessing the stack that high (on the first assignment to B) might be what's causing the segfault.


Your 3rd code doesn't work either (on my system at least).

Try allocating memory to array a on the heap rather(when dimensions are large).


Both matrices don't fit in the limits of your memory. You can allocate only one at a time.

If you define Y as 3000 instead of 6000, your program should not issue segfault.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜