开发者

passing a structure into a function creates a sefault error

both of these functions are (under my compiler at least) guaranteed to create a seg fault, yet i have no idea why. i really like their functionality and i have seen similar examples, so i am curious to know what is going wrong here or how to do what i think this actually does, which is passing a "level开发者_如何学JAVA" into some function and then being able to manipulate its variable (eg lvl.lvl_cl[x][y][z] = some_number) and then pass it back for further use

any help is appreciated :)

typedef struct {
    int lvl_cl[500][500][50];
    char lvl_ch[500][500][50];
} level;

level plugh(level * in_lvl){
    in_lvl->lvl_cl[444][444][44]++; //it segfaults even if this line is removed
    return * in_lvl;
}

level foo(level inlvl){
    inlvl.lvl_cl[443][443][43]++;   //it segfaults even if this line is removed
    return inlvl;
}

int main(void){
    level world;
    plugh(&world);
    foo(world);
    return 0;
    }


Stack overflow?

Seriously, have you ever considered how big your struct is? If you store it on the stack it will overflow...

Try a sizeof(level), it would be interesting to see the actual size.

EDIT: If you need something that big, you really should consider where and how you store it. If you pass it to a function, you will make a copy of the structure and place it on the stack. If you return the struct you will most likely need another copy of the stack.

Do you really need to pass and return the struct? If not, you could place it in normal static memory (a plain global variable) or allocation one on the heap. Either way, if you pass around a pointer to it, it would only consume a fraction of the full structure.


First of all, that's a LOT of memory:

500x500x50x1 (because 1 byte in char) + 500x500x50x4 (because 4 bytes in an int) = 59.605MB of memory.

You are storing this all on the stack, rather than using pointers and allocating it on the heap, which should cause a stack overflow.

Furthermore, in your plugh and foo functions, you are returning a whole new struct. Why pass by pointer, modify the object, and then return a copy? Every time you call these functions you are allocating another 59.605MB of memory because you are returning a copy. However, since you aren't using the copy, the compiler is probably optimizing and removing this expensive copy.


The problem is that you are putting around 100MB on the stack and your stack isn't that big.

You need to start using pointers to this level struct and heap allocation rather than trying to copy it onto the stack!


It segfaults

0x8048471 <main>:       lea    0x4(%esp),%ecx
0x8048475 <main+4>:     and    $0xfffffff0,%esp
0x8048478 <main+7>:     pushl  -0x4(%ecx)
0x804847b <main+10>:    push   %ebp
0x804847c <main+11>:    mov    %esp,%ebp
0x804847e <main+13>:    push   %esi
0x804847f <main+14>:    push   %ebx
0x8048480 <main+15>:    push   %ecx
0x8048481 <main+16>:    sub    $0xb2d060c,%esp
0x8048487 <main+22>:    lea    -0x7735958(%ebp),%eax
0x804848d <main+28>:    lea    -0x3b9acb8(%ebp),%edx
0x8048493 <main+34>:    mov    %edx,0x4(%esp)      <<---- segfaults here
0x8048497 <main+38>:    mov    %eax,(%esp)
0x804849a <main+41>:    call   0x80483f4 <plugh>

The fault occurs when addressing the new stack pointer after allocating a stack frame of 62,500,000 bytes (32 bit int).

Large structures should always be passed by reference. Especially considering the logic of foo().


Every time you call foo function it copies the whole world structure and it is quite big. Try to pass the pointer:

void foo(level *inlvl){
    inlvl->lvl_cl[443][443][43]++;
}


Did you try a function that just passes a ref to your structure and returns nothing? Something along the lines void foo(level* var){// your code here that modifies var} And in main you just call foo(&myVar).

Passing such a huge structure as a parameter to a function or having it as a return value might create a bit of trouble for you. Also if you really need to have a return value try also returning a reference to your struct. like level* foo(level* in){ //your code here }.

And in main you just dereference the function result like level myLvl= *(foo(&myOtherLvl)). That way all you pass in your function are refs to your structs, witch are basically integers. Hope this helps

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜