Reputation: 65
For some reason, the values of a passed struct change without me accessing them. I found this out by debugging with Visual Studio. Here is the code:
bool Screen::blitSurface(SDL_Surface* src, int x, int y, SDL_Rect* rect) {
SDL_Rect* offset;
offset->x = x;
offset->y = y;
SDL_BlitSurface( src, rect, screen, offset );
return true;
}
The struct that is changing is 'rect'. When it is passed, rect->x is 0 and rect->y is 16. However, at the next breakpoint (offset->x = x;) rect->x is a random number (for instance, -13108), same with rect->y. Does anybody have an idea as to why this happens? I'm completely lost, and have no idea where to start.
--EDIT--
Ok, I updated the code to this, but it's still having the problem.
bool Screen::blitSurface(SDL_Surface* src, int x, int y, SDL_Rect* rect) {
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface( src, rect, screen, &offset );
return true;
}
However, it did get me thinking. If I create a local struct, and return a pointer to it, it is deleted once the function completes? For example, does this work?
SDL_Rect* getRect(int x, int y, int width, int height) {
SDL_Rect rect;
rect.x = x;
rect.y = y;
rect.w = width;
rect.h = height;
return ▭
}
This is where I get the 'rect' variable that I am passing to 'blitSurface'.
Upvotes: 1
Views: 3214
Reputation: 213837
This code is wrong:
SDL_Rect* offset;
offset->x = x;
offset->y = y;
Here, offset
is an uninitialized pointer. Accessing an uninitialized pointer is always an error, even though it doesn't always crash your program. I wouldn't use a pointer here.
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface(src, rect, screen, &offset);
When you access an uninitialized pointer (or an invalid one), you are basically telling your computer to scribble over an arbitrary part of your computer's memory. In a best-case scenario, the program crashes. In a worst-case scenario, it doesn't crash -- think about that for a moment.
This code is also wrong:
SDL_Rect rect;
// ...
return ▭
The pointer to rect
is invalid as soon as the function exits. Again, I wouldn't use a pointer here.
SDL_Rect getRect(int x, int y, int width, int height)
{
SDL_Rect rect;
rect.x = x;
rect.y = y;
rect.w = width;
rect.h = height;
return rect;
}
The SDL_Rect
structure is small enough and trivial enough that you should feel free to return it from a function. If you need to pass the result to an SDL function that takes a pointer, do it this way:
SDL_Rect r = getRect(...);
SDL_Some_Function(..., &r, ...);
Pointers are dangerous in C and C++: That's not to say you shouldn't use them. But if you don't know exactly what conditions make a pointer valid or invalid, then your program will be incorrect. The compiler will not help you figure this out -- although static analysis tools like Clang might help.
Unlike C and C++, most other languages (like Python, C#, Java, Haskell, Lisp, Perl, Ruby) do not allow you to create invalid pointers unless you really work at it.
Upvotes: 2
Reputation: 258688
Two words: Undefined behavior.
SDL_Rect* offset;
offset->x = x;
offset->y = y;
You're accessing an uninitialized variable.
Either allocate offset
:
SDL_Rect* offset = new SDL_Rect;
or have it in automatic memory:
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface( src, rect, screen, &offset );
Upvotes: 2