[SOLVED] Seg Fault. Memory address not being passed to function.
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Seg Fault. Memory address not being passed to function.
I am writing a game in C with SDL. I can successfully display one image on the screen and animate it. However, I am having a lot of issues getting the background to display using the same method. I was asking for help on SDL related forums, but I determined that the issue is not SDL related, and it is actually a pointer issue. However, I can't find where I'm going wrong.
Ok, there it is. I added a bunch of printf to determine where and why this is happening. I changed "struct image backdrop" to "struct character BG" so I could do the exact same thing with Main and BG. Main works, BG still does not. I also use a circularly-linked list for an animation. Here is some sample output from the program:
The first few lines confirm that the images are getting loaded correctly. Then my SDL version numbers. Then the memory addresses of Main.active and Main.active->image before and after it gets passed to show(). Then 1 2 3 4 showing that show() didn't crash that time.
As you can see from the last 3 lines before the segfault, the problem is occurring in the show function. I try to pass BG to it, but the function sees it as 0. weird because when I do the exact same thing with Main it works fine. If I just comment out the line where I show(BG), then it runs fine and I see my little walking guy on a black screen. The memory address of BG.active->image isn't getting passed into show(), I confirmed this with GDB. What is going on?
The memory address of BG.active->image isn't getting passed into show()
obj isn't a pointer.
Nor is obj a number, so that printf doesn't make sense. You should compile with -Wall and -Wextra so gcc will warn you about incorrect format strings. Also it would help if you added the name of the variable you are printf'ing because right now it's difficult to follow what the output means.
I agree with ntubski regarding the error in the printf. But I don't see how that error invalidates the conclusion you reached about the malfunction. You seem to have pretty solid evidence that BG.active->image is valid right before being passed into show() as obj, but obj is not valid in show().
I really doubt that the difference is BG vs. MAIN. I think the difference is 0,0 vs. Main.physics.x,Main.physics.y as if the compiler didn't know that it must cast 0,0 into 0.0,0.0
I think the earlier definition of show() should make the compiler know it must do that cast. I'm not sure what rule of C I'm missing. But given the evidence that the compiler doesn't know, you ought to try doing it yourself:
use
Code:
show(0.0,0.0,BG.active->image);
instead of
Code:
show(0,0,BG.active->image);
BTW, I really don't like passing the image to show() by value rather than by pointer. But I don't see any way that can be part of the problem.
I agree with ntubski regarding the error in the printf. But I don't see how that error invalidates the conclusion you reached about the malfunction. You seem to have pretty solid evidence that BG.active->image is valid right before being passed into show() as obj, but obj is not valid in show().
I really doubt that the difference is BG vs. MAIN. I think the difference is 0,0 vs. Main.physics.x,Main.physics.y as if the compiler didn't know that it must cast 0,0 into 0.0,0.0
I think the earlier definition of show() should make the compiler know it must do that cast. I'm not sure what rule of C I'm missing. But given the evidence that the compiler doesn't know, you ought to try doing it yourself:
use
Code:
show(0.0,0.0,BG.active->image);
instead of
Code:
show(0,0,BG.active->image);
BTW, I really don't like passing the image to show() by value rather than by pointer. But I don't see any way that can be part of the problem.
Oh my God! That was the problem the whole time?!?! That's ridiculous! Is this a bug in the compiler? Or is this normal behavior? I have never heard of this before.
Anyway, I tried
Code:
show(0.0,0.0,BG.active->image);
and it worked perfectly. I'm just having a hard time believing that gcc would pass an int to a function that wants a double and not even warn me about it. Thank you johnsfine! You saved this project!
BTW. Correct me if I'm wrong. I probably am, this is probably my (forced) Java classes polluting my memory, but BG.active->image should never get passed by value, shouldn't it get passed by reference? I think I'm mixing up Java and C. If it is getting passed by value, then I've made a horrible mistake, I'm wasting quite a lot of resources.
I WAS passing a pointer, but I changed it once I started having problems. So, fortunately, this is the only place in my code where I do this.
I was wondering if it was a difference between the code you posted and the code you tested. For example, did you actually have show() and gameRender() in different source files, so that the compiler compiles gameRender() without the declaration of show(). Then the behavior would be expected. Neither the compiler nor the linker would complain that the signature for show() assumed by gameRender() fails to match the actual signature.
If what you tested was exactly what you posted, I don't understand the compiler behavior. But that is not enough of a reason to jump to the conclusion of a compiler bug.
Quote:
this is probably my (forced) Java classes polluting my memory, but BG.active->image should never get passed by value, shouldn't it get passed by reference?
It either gets passed by value or it gets copied and the copy gets passed by reference (which of those actually happens is an implementation detail internal to the compiler). It certainly does not pass the original by reference.
Quote:
I think I'm mixing up Java and C.
I think so.
Quote:
If it is getting passed by value, then I've made a horrible mistake, I'm wasting quite a lot of resources.
The object consisted of only two pointers. Pass by value adds just a little cost to the calling function. If it really passes by value (rather than pass a copy by reference) then it saves a little cost (compared to the usual pass by pointer) within the called function. In this case it doesn't net to any big difference.
I just think it is a bad practice. In other situations, it will cost a lot and/or give unexpected results.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.