1

I'm pretty sure this is not unexpected at all, I'm probably misunderstanding something. I'm trying to call one of the overloaded constructors as such:

SDL_RenderCopy(SDL_Renderer*, SDL_Texture*, SDL_Rect*, SDL_Rect*);

The problem came when I made a static method in a class to retrieve SDL_Rect pointers as such:

static SDL_Rect* getRectangle(rect r) {
    SDL_Rect rectangle{ r.x, r.y, r.w, r.h };
    return &rectangle;
}

So the call is like:

SDL_Rect* r = MyClass::getRectangle(srcRect);
SDL_Rect* r2 = MyClass::getRectangle(destRect);
SDL_RenderCopy(renderer, texture, r, r2);

They are all pointers and are returning coherent values, but for some reason I don't understand, the rectangles that I'm fetching from my class when passed to SDL, are not scaling according to the values of the rectangles. But if I change my static method to return a copy of SDL_Rect, everything works as expected, as such:

static SDL_Rect getRectangle(rect r) {
    SDL_Rect rectangle{ r.x, r.y, r.w, r.h };
    return rectangle;
}

And the call:

SDL_Rect r = Video::getRectangle(srcRect);
SDL_Rect r2 = Video::getRectangle(destRect);

SDL_RenderCopy(renderer, texture, &r, &r2);

Bruno Giannotti
  • 323
  • 2
  • 13
  • Is it because SDL_Rect is a struct and not on the heap and therefore gets destroyed at the end of the scope and therefore I can't use pointers to it outside of the scope? (I mean, I can, but the memory no longer has my data) – Bruno Giannotti Apr 16 '20 at 14:39
  • Does this answer your question? [Can a local variable's memory be accessed outside its scope?](https://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) – drescherjm Apr 16 '20 at 14:40

1 Answers1

3

The problem is in your function getRectangle():

static SDL_Rect* getRectangle(rect r) {
    SDL_Rect rectangle{ r.x, r.y, r.w, r.h };
    return &rectangle;
}

You are returning the address of an object, rectangle, that has automatic storage duration. Therefore, the object doesn't exist after the control returns from the function.


You may want to allocate an SDL_Rect on the heap and return its address instead:

static SDL_Rect* getRectangle(rect r) {
    return new SDL_Rect{ r.x, r.y, r.w, r.h };
}
JFMR
  • 23,265
  • 4
  • 52
  • 76
  • Yeah thats what I thought. And I had no idea I could allocate a struct like this! I thought I had to make a class to be able to use `new` and get a pointer as return. Thank you very very much! – Bruno Giannotti Apr 16 '20 at 14:42
  • In `c++` a class or struct are the actually the same with the difference being that a struct all members are public by default and a class they are private. – drescherjm Apr 16 '20 at 14:45
  • 1
    Right, you can even use `new` with fundamental types. For example: `int* p = new int(1)`. – JFMR Apr 16 '20 at 14:47
  • 2
    Out of curiosity: Why not `static SDL_Rect getRectangle(rect r) { return SDL_Rect{ r.x, r.y, r.w, r.h }; }`? What has been `new`ed should be `delete`d. That's not an issue in my case. – Scheff's Cat Apr 16 '20 at 14:49
  • Well, I apologize, I mostly come from C# and I always differentiate them by thinking that structs were passed as value instead of reference and therefore I could never allocate it without using a special parameter `out`. – Bruno Giannotti Apr 16 '20 at 14:50
  • @Scheff No reason at all. I just wanted to get the pointer "automatically" without needing to indicate the reference on the function call, which is pretty stupid considering the side effects. – Bruno Giannotti Apr 16 '20 at 14:53
  • 2
    @BrunoGiannotti Ah, you just tried this. It's not as bad as you might afraid. There is something like [Return Value Optimization](https://en.cppreference.com/w/cpp/language/copy_elision) which makes it more optimal as you would expect on the first glance. – Scheff's Cat Apr 16 '20 at 14:53