Confusion about Pointers :S (and other dilemmas)

Hi there,
I have a couple of questions I'd like to ask about the usage of pointers. I wanted to experiment a bit with SDL but noticed right away that the SDL_Surfaces for example are created as pointers :S

So my first question would be:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Image
{
public:
	Image(SDL_Surface *surface);
	//Destructor?
	
	FloatRect rect;
	
	SDL_Surface *getSurface();
	void setSurface(SDL_Surface *surface);
	void loadImage(string path);
private:
	SDL_Surface *surface_;
};


In this code snippet I would probably need to create a destructor because the surface_ is a pointer, right? What would this destructor consist of? Calling SDL_FreeSurface(surface_)?

My next questions are related to the function definitions of my class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//1. What if surface goes out of scope?
Image::Image(SDL_Surface *surface):
rect(SDL_Rect())
{
	surface_=surface;
	rect=FloatRect(surface_->clip_rect);
}

SDL_Surface *Image::getSurface()
{
	return surface_;
}

//2. Memory leak with previous surface_?
void Image::setSurface(SDL_Surface *surface)
{
	surface_=surface;
}

//2. Memory leak with previous surface_?
void Image::loadImage(string path)
{
	surface_=IMG_Load(path.c_str());
}


1.: If I construct the Image with a SDL_Surface that goes out of scope earlier than my Image itself, what happens to surface_? (Because I think it would still point to a memory address but probably not the one of the original surface I created the Image with, right?)

Or a similar thing I think would be if I saved a surface I got with getSurface() (from an Image image) as SDL_Surface *surface. If this surface went out of scope before image would, what happens to surface_?

2.: Finally the methods I marked with 2. would cause memory leaks if surface_ was previously assigned to something else, right? Would I first free the previous surface_(if there was one)?

I'd also like to ask an additional question about makefiles:
If I have the following structure:
FloatRect.cpp includes FloatRect.h
Image.cpp includes Image.h which includes FloatRect.h
main.cpp includes Image.h

Currently I have my makefile structured like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CFLAGS=-m32 -Wall
SDL=C:\Users\fuerchter\Downloads\SDL-devel-1.2.15-mingw32\SDL-1.2.15
LIBS=-lmingw32 -lSDLmain -lSDL -lSDL_image

all: main.o FloatRect.o Image.o
	g++ $(CFLAGS) main.o FloatRect.o Image.o -L$(SDL)\lib $(LIBS)
	
main.o: main.cpp
	g++ -c $(CFLAGS) main.cpp -I$(SDL)\include
	
Image.o: Image.h Image.cpp
	g++ -c $(CFLAGS) Image.cpp -I$(SDL)\include
	
FloatRect.o: FloatRect.h FloatRect.cpp
	g++ -c $(CFLAGS) FloatRect.cpp -I$(SDL)\include


But I am first of all not sure whether I'm supposed to put the Header files into the prerequisites. Also if I changed FloatRect.h the Image.o target wouldn't be compiled again. Is this supposed to happen? Can I still improve this makefile? (because I'm just not sure whether I am writing them in the proper way >.<)

I would appreciate it very much if anyone could help me clear up these matters :D

//EDIT:
Oh and by the way is there a way for me to write programs with SDL while still having a console to write to because at the moment I am writing all my testing stuff in the caption of the window ^^
Last edited on
In your first example, your constructor takes the surface as a parameter, therefore it is the responsibility of the external code to properly destruct it - you are just given access to it, so you should not destroy it without permission.

@1. That's not a problem your class needs to be concerned with (as you have it currently), but yes, your class would have a angling pointer.
@2. Make up your mind: does your class manage the surface, or does it just have access to it?
Last edited on
In this code snippet I would probably need to create a destructor because the surface_ is a pointer, right? What would this destructor consist of? Calling SDL_FreeSurface(surface_)?


If you don't know the semantics of your own class, then how are we supposed to know?

If I construct the Image with a SDL_Surface that goes out of scope earlier than my Image itself, what happens to surface_? (Because I think it would still point to a memory address but probably not the one of the original surface I created the Image with, right?)


Wrong. The pointer goes out of scope, but this does absolutely nothing to the memory being pointed at. It doesn't change the copy of the pointer you're holding either.

2.: Finally the methods I marked with 2. would cause memory leaks if surface_ was previously assigned to something else, right? Would I first free the previous surface_(if there was one)?


You leak memory if you don't free up resources you create. So it depends on how your class is supposed to behave - if your Image object are supposed to be the sole owners of the surface, then yes you'd leak memory there. If the Image is just supposed to reference that surface, and the owner is something else (for example a resource manager) then not necessarily.

Oh and by the way is there a way for me to write programs with SDL while still having a console to write to because at the moment I am writing all my testing stuff in the caption of the window ^^


You can start the program from a console.
About the makefile
$ g++ -MM *.cpp
will generate the dependencies.
You can start the program from a console.


I still can't cout to the console then though (I think it has to do with SDLmain?).

If you don't know the semantics of your own class, then how are we supposed to know?


My class is supposed to pair a SDL_Surface up with a FloatRect because it seems hard to do time-based (instead of frame-based) movement with the int rectangles SDL provides.

Also with my question I was just trying to reinforce what I read in http://www.cplusplus.com/forum/general/8767/ namely when exactly I need a destructor. I find your wording to come across as a bit insulting, but I guess that may be my fault for getting offended rather easily by stuff people say on the internet.
Last edited on
About the makefile

$ g++ -MM *.cpp

will generate the dependencies.


Thanks for the hint. It seems to print the dependencies to the console then?
For example my main.cpp then generates:
main.o: main.cpp Image.h (then a lot of SDL headers) FloatRect.h

Based on that I structured my makefile to look like the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CFLAGS=-m32 -Wall
SDL=C:\Users\fuerchter\Downloads\SDL-devel-1.2.15-mingw32\SDL-1.2.15
LIBS=-lmingw32 -lSDLmain -lSDL -lSDL_image

all: main.o Image.o FloatRect.o
	g++ $(CFLAGS) main.o Image.o FloatRect.o -L$(SDL)\lib $(LIBS)

main.o: main.cpp Image.o FloatRect.o
	g++ $(CFLAGS) -c main.cpp -I$(SDL)\include
	
Image.o: Image.cpp Image.h FloatRect.o
	g++ $(CFLAGS) -c Image.cpp -I$(SDL)\include
	
FloatRect.o: FloatRect.cpp FloatRect.h
	g++ $(CFLAGS) -c FloatRect.cpp -I$(SDL)\include


(so basically I added the FloatRect and Image dependencies to main.o and the FloatRect dependency to Image.o)
Last edited on
You still need to make up your mind: does your Image class take full responsibility for the SDL_Surface, or does it just get permission to access someone else's SDL_Surface? Your class is currently a mix.
The class is supposed to own the SDL_Surface (so, yes, take responsibility). Still I'd like to be able to blit the surface owned by the Image outside of the Image itself (thus I would have to have a getter for the surface, which apparently complicates things).

I read up a bit on deep copy vs shallow copy and such now but I guess that doesn't apply to my issue? (I don't think a SDL_Surface can be deep copied?)

Also: Should I consider using/learning smart pointers? I've read that shared pointers and such may help with the aforementioned ownership issues? I didn't use boost/smart pointers yet so I would probably have to learn a bit of new stuff in that area first :S
Since you want your Image class to own the SDL_Surface, it should construct it itself in its ctor, rather than take a pointer to it as a parameter.

Shouldn't an SDL_Surface be deep-copy-able? You would make a new one and copy settings and content to it from the old one.

You will indeed want to look into smart pointers. If SDL_Surface needs to be freed by calling some other function than default delete, you will need to give that information to the smart pointer so it can get deleted properly.
> it should construct it itself in its ctor, rather than take a pointer to it as a parameter.
But there are several ways to construct a surface, and it's the client that should decide.

> I read up a bit on deep copy vs shallow copy and such now but I guess that doesn't apply to my issue?
You do need to release the surface.
A shallow copy would attempt a double release (error)
SDL_surface provides a counter for shallow copy and a clone function `ConvertSurface()' for deep copy.
You could provide no copy mechanism too.
ne555 wrote:
But there are several ways to construct a surface, and it's the client that should decide.
In that case, he either needs to account for alternative ways to destruct & reconstruct the SDL_Surface (it could be allocated with new, new[], malloc, some sort of SDL_Create_Surface, placement new, etc.) or he needs to place the lifetime responsibility of the SDL_Surface outside of his class. (I'd opt for the second option)
I don't understand what you meant with `alternative ways', ¿mind to provide an example?

Take by instance http://www.cplusplus.com/reference/memory/unique_ptr/unique_ptr/
unique_ptr is responsible of the lifetime, however it has no idea of how to construct a T.
It has as a template parameter a deleter to use, I don't think the Image class should handle it at this point.
¿? I am not talking about the destructor, but the constructor.

Consider virtual void wxWindow::AddChild (wxWindow *child)
When the parent window dies, it kills all its children. It has the lifetime responsibility.

You are supposed to used it like
1
2
3
wxWindow main(/*params*/);
main.AddChild( new wxMenuBar(/**/) );
main.AddChild( new wxGLCanvas(/**/) );


¿what are the `alternative ways' that you are talking about?
The issue I have is, who frees the memory and how?
1
2
3
Image::~Image(){
   SDL_FreeSurface( surface_ );
}
OK, so SDL_Surface may only be created in such a way that SDL_FreeSurface can free it. I forgot SDL used C class design (being written in C I should have guessed)
Topic archived. No new replies allowed.