Advertisement

Initialize SDL_Rect Instances with a function

Started by November 27, 2011 11:24 PM
5 comments, last by rip-off 13 years ago
Hey, I'm using SDL to create a small tech demo(for Programming). I was trying to lower my amount of code by creatign a 'constructor' for SDL_Rect.
In an earlier version I just did this:

SDL_Rect Rect;
Rect.x = 300;
Rect.y = 400;
Rect.h = 50;
Rect.w = 50;


I created a new function in my code and tried to initialize my Rect Instances using it.
This is the function:

SDL_Rect *Init(SDL_Rect *Rect, int XPos, int YPos, int Width, int Height)
{
Rect->h = Height;
Rect->w = Width;
Rect->x = XPos;
Rect->y = YPos;
return Rect;
}

And This is inside Main:
SDL_Rect *Rect = Init(Rect, 300, 400, 50, 50);

It doesn't give me any syntax errors, but when I go to run it.
[color="#ff0000"]Run-Time Check Failure #3 - The variable 'Player' is being used without being initialized.
You could just use aggregate initialization for it:

SDL_Rect Rect = { 300, 400, 50, 50 };
Advertisement
What are your pointers pointing at? wink.gif
You never assign them.

You go like this:

MyPointer = MyFunction(MyPointer);

MyFunction(MyPointer)
{
return MyPointer;
}



You are setting an uninitialized pointer to point to the result of a function... but you are passing in your pointer (uninitialized) to that function and then returning that uninitialized pointer to initialize itself. My sentence doesn't really make sense... because I'm trying to describe your code which also doesn't make sense. tongue.gif

If you cut out your function, which never actually creates any variable to point to anyway, you basically get this:
SDL_Rect *Rect = Rect;
...which does nothing worthwhile or meaningful.

Have you learned how pointers work? Just like my dog, they can bite you if you don't know how to handle them properly - but also just like my dog, they aren't anything to fear either, you just have to learn how to handle them - which is easy, once you learn it. Rather then go into a pointer tutorial here, many programmers have already written loads of pointer tutorials just a google away, and can explain it better than I can. I strongly encourage you to go review some of those; meanwhile I'll just help you rewrite your function.

Here are four different functions that do what you want - they all work fine. If you have any questions about how they work, just ask! smile.gif

Return-by-value version:
SDL_Rect Init(int XPos, int YPos, int Width, int Height)
{
SDL_Rect Rect;
Rect.h = Height;
Rect.w = Width;
Rect.x = XPos;
Rect.y = YPos;

return Rect;
}

//Use like this:
SDL_Rect myRect = Init(5, 5, 50, 20);


Pass-by-reference version:


void Init(SDL_Rect &Rect, int XPos, int YPos, int Width, int Height)
{
Rect.h = Height;
Rect.w = Width;
Rect.x = XPos;
Rect.y = YPos;
}

//Use like this:
SDL_Rect myRect;
Init(myRect, 5, 5, 50, 20);


Pass-by-pointer version:


void Init(SDL_Rect *Rect, int XPos, int YPos, int Width, int Height)
{
Rect->h = Height;
Rect->w = Width;
Rect->x = XPos;
Rect->y = YPos;
}

//Use like this:
SDL_Rect myRect;
Init(&myRect, 5, 5, 50, 20);


Dynamic memory / return-by-pointer version:


SDL_Rect *Init(int XPos, int YPos, int Width, int Height)
{
SDL_Rect *Rect = new SDL_Rect;
Rect->h = Height;
Rect->w = Width;
Rect->x = XPos;
Rect->y = YPos;

return Rect;
}

//Use like this:
SDL_Rect *myRect = Init(&myRect, 5, 5, 50, 20);

//And don't forget to free it when done (or you'll have a memory leak).
delete myRect;
@Servant of the Lord
That was incredibly in depth, thanks. I have learned some of the basics on how pointers work, but most websites just explain the relationship between pointers and memory. This leads to me being confused because, although I understand pointers, I do not know when to use them instead of variables.

The examples you gave are great. I am wondering if any one has an advantage over the other.
You almost certainly do not want to be dynamically allocating SDL_Rect instances. So I would discount that one immediately. The choice between the others is mainly stylistic. I wouldn't use the pointer version because there is no immediate obvious behaviour in the case the pointer is null.

That leaves it as a toss up between pass by reference and return by value. Because it is a simple value object, I would probably go with the version that returns a rectangle:

SDL_Rect make_rect(int x, int y, int w, int h)
{
SDL_Rect rect = { x, y, w, h };
return rect;
}

It makes it easier to initialise during declaration, and can be used in an initialiser list.
I wouldn't use the pointer version even if it did check for NULL, since a reference would be much better suited for passing and editing parameters that don't get reassigned in the function itself. wink.gif
I only included the pointer and dynamic memory examples because the OP's function looked like it was trying to do that (by returning a pointer).
You're right though, I should've added a warning or a link to more information.
Advertisement

I wouldn't use the pointer version even if it did check for NULL...
[/quote]
The problem is, what should it do when passed NULL? Silently return? Return an error code, which will likely be ignored? Throw an exception? Use an assert(), and hope you catch the errors in a Debug build?


You're right though, I should've added a warning or a link to more information.
[/quote]
No, you gave a good answer, exhaustively listing the possibilities. You even explicitly requested the OP ask more questions if they required it.

I just answered the OP's follow up question. I wasn't criticising your answer at all.

This topic is closed to new replies.

Advertisement