Jump to content
  • Advertisement

RonnieCassinello

Member
  • Content Count

    7
  • Joined

  • Last visited

Community Reputation

100 Neutral

About RonnieCassinello

  • Rank
    Newbie
  1. Hello everyone, After searching, I've found plenty of hints but no definite answer to my question - if I insert into a STL map, will memory ever be reallocated, or is the address of any inserted object fixed? I've tried testing it, and I've not found anything that refutes this, but it could be just that I have performed the tests properly. Maybe I should explain what I'm trying to do rather than just ask a specific question, as there's probably a better way of doing this anyway. I have three maps which I'm using as sparse arrays, and the key for each is just an unsigned int, vis: map<unsigned int, Fruit> Fruits map<unsigned int, Seed> Seeds map<unsigned int, Recipe> Recipes These are just used to contain my objects, and all the insertions are done as part of programme initialisation, and then they are left alone until destruction. Importantly, they are used to contain ALL instances of these objects in the program. The complication comes because each of the classes Fruit, Seed and Recipe classes needs a way of accessing an instance of the other two classes. I felt that rather than just giving them the key number and then passing the whole map by reference, it would be neater to use a pointer, which is obtained during initialisation, eg: pFruit = &Fruits[45]; I liked this approach as even if Fruits[45] hadn't been created yet, the map itself would construct a new Fruit object and return its address. Later on in initialisation, the object will usually be altered, but if not it wouldn't matter as Fruits[45] would still have been constructed. Which brings me to my problem - the address is only obtained once, during initialisation. So will the address given by &Fruits[45] always be valid, even if the initialisation inserts a few hundred other Fruit objects into the map AFTER - or is there a much neater way of achieving all this anyway?
  2. RonnieCassinello

    C++11 'nullptr' - does it convert to 'false' implicitly?

    Thank you both for the quick replies. That's great! As for the Boost library, that's on my 'to do' list of things to look at. At the moment, I'm working my way back through Ivor Horton's Beginning C++ (first edition and positively battered to bits!), and sighing at how much I've forgotten, whilst also applying it to simple projects (and firmly blurring the line between using c and c++ for good measure). But yes, I've heard so many good things about Boost that I definitely want to learn anout it. As comfortable as I am using pointers, I still drop the ball from time to time. Thanks again, Ronnie
  3. Hi all, I'm currently starting a new project to just mess about with inheritance and polymorphism (something I've not even looked at for a good 10 years), and I'd like my code to use the new nullptr keyword. The problem I have is that my compiler doesn't actually support it yet, so as a hack I've, defined it as a const int, like so: const int nullptr = 0;...for the time being. This has left me curious as to whether my code will be broken when I do get a compiler that supports nullptr - will nullptr implicity convert to 'false'? Perhaps it's best with an example. Say I had a pointer to an object, which may contain nullptr or may contain a valid address. Would the following snippet still work? if (pObject) { pObject->someFunction(); // and other stuff } else { pObject = new Object; // and other stuff } Simlarly, if I had a vector of pointers, some of which are set to nullptr, could I still use this to delete the objects in a class destructor? for (unsigned int i = 0; i < pObjects.size(); ++i) if (pObject) delete pObject; Many thanks, Ronnie
  4. RonnieCassinello

    C (C++) / Code::Blocks / printf() "%Lf" warning...?

    Thanks for the replies and advice. I think that with my lack of familiarity with changing any of the inner workings of the IDE, combined with not envisaging needing to use 'long double' in any of my current projects, I think for the time being I will just cast it to 'double' before using fprintf(). Thanks again, Ronnie
  5. Hi all, I've come across a curious problem which I'm not sure is my fault or someone else's. I was attempting to create a C++ class interface for simple C text mode file IO operations (for silly reasons of personal bias, I just don't like C++ streams), and came across a problem with fprintf(). So as not to bore you all with the details of the class, I've been able to reproduce the problem exactly in just a simple a program: #include <stdio.h> int main() { long double Pi = 3.14159265358979L; printf("%Lf", Pi); return 0; } And the problem is this: When I attempt to compile I get the following warnings: warning: unknown conversion type character 'L' in format warning: too many arguments for format ...And then when running the actual output is nothing at all like Pi. If I attempt to swap the %Lf to %lf, I get warned that %lf is for double, not long double. I've read through various different printf() documentations I've found on the web and they all seem to be saying that I'm doing it right, but I'm never convinced about my own abilities. So is this a problem with what I've written or is there something wrong with the compiler (Code::Blocks 10.05)? Thanks for reading this. Ronnie
  6. RonnieCassinello

    C++ / Putting a class that has an SDL_Surface* member in a vector

    Aha! Thank you very much. Being new to writing copy constructors and assignment operators, I had wrongly assumed that my copy constructor could just call the assignment operator. Explicitly writing a seperate copy constructor did the trick: GrfImage::GrfImage(const GrfImage &Original) { Grf = NULL; Loaded = false; GrfClip.resize(0); GrfClipReg.resize(0); if (Original.Loaded) { Grf = SDL_DisplayFormat(Original.Grf); Loaded = true; GrfClip = Original.GrfClip; GrfClipReg = Original.GrfClipReg; } }; After running and closing my program several times, I haven't hit any errors and more importantly I don't appear to be leaking any memory. I feel quite humbled as this is the first time in 25 years of programming that I've ever asked for help - a reference book or google being my weapons of choice. I suppose the important lesson learned here is that I should I RTFM more carefully sometimes - I had always thought that vector::push_back created a new empty object then assigned an existing object into the new one, whereas I'm now 99.9% sure that it calls the copy constructor instead. @BeerNutts: Thanks also for your suggestion. I tried that first as it seemed the easier option, but alas it wouldn't compile - and I didn't think the that original object going out of scope was the issue anyway, as when I did it as C array I didn't get a problem. Thanks again, Ronnie
  7. Hello all, For nearly two days now I've googled and tried so many different approaches to getting this to work, but still with no luck. Basically, I would like to have a very simple class (or a struct if I really have to) that contains an SDL_Surface*, and then have a std::vector to put them in. The problem comes that no matter how 'safe' I think my approach or class is, as soon as I try to put it in a vector, I get a seg fault. Background: In making a simple 2D game, I prefer to have a limited number of SDL_Surface's, each containing multiple sprites, with a vector of SDL_Rect's to define each particular sprite clip. This worked great when I was taking a structured approach, I would simply use something like this as global variables: vector<SDL_Surface*> Graphics; // Vector of my graphics vector< vector<SDL_Rect> > Clipping; // 2D vector of clipping information vector< vector<bool> > ClipRegister; // 2D vector of bools to tell me if a particular member of Clipping had be defined The downside is that the game itself had to handle the loading and unloading of graphics, and I wanted to get away from this and put all the graphics functions in a class, and let the game get on with just being a game. It would obviously also have the advantage of being reusable in for other games. This all part of a larger project to make a single class that encapsulates all my graphic needs safely. So step one towards this was to make a simple class (I'm learning as I go and didn't want to over-stretch myself): class GrfImage { public: SDL_Surface* Graphics; vector<SDL_Rect> Clipping; vector<bool> ClipRegister; }; This obviously goes against all the principles of encapsulation, but my plan is to implement this as my confidence grows. But here I got my first problem. Using a one-off 'GrfImage', things worked fine with this temporary hack, however as soon as I made a vector of them (e.g., vector<GrfImage> Images;) I got seg faults whenever I used SDL_FreeSurface(Image.Graphics);, even having ensured that an image had been loaded and that the index into the vector was legal. So I thought "Well I'm clearly not managing the memory properly", and pushed on to an encapsulated version: Header file: class GrfImage { public: GrfImage(); GrfImage(const GrfImage &Original); GrfImage& operator= (GrfImage const &Original); ~GrfImage(); bool ImgLoadBMP(string FName, SDL_Color Key); bool ImgLoad(string FName, SDL_Color Key); bool ImgBlitBMP(short x, short y, SDL_Surface* Dest); bool ImgBlit(short x, short y, unsigned short i, SDL_Surface* Dest); private: SDL_Surface* Grf; bool Loaded; vector<SDL_Rect> GrfClip; vector<bool> GrfClipReg; }; Source file: #include "grfio.h" using namespace std; GrfImage::GrfImage() { Grf = NULL; Loaded = false; GrfClip.resize(0); GrfClipReg.resize(0); } GrfImage::GrfImage(const GrfImage &Original) { *this = Original; }; GrfImage& GrfImage::operator= (GrfImage const &Original) { if (Loaded) SDL_FreeSurface(Grf); if (Original.Loaded) { Grf = SDL_DisplayFormat(Original.Grf); Loaded = true; } else { Grf = NULL; Loaded = false; } GrfClip = Original.GrfClip; GrfClipReg = Original.GrfClipReg; return *this; } GrfImage::~GrfImage() { if (Loaded) SDL_FreeSurface(Grf); }; bool GrfImage::ImgLoadBMP(string FName, SDL_Color Key) { if (Loaded) { SDL_FreeSurface(Grf); Grf = NULL; } SDL_Surface* TempGrf = NULL; TempGrf = SDL_LoadBMP(FName.c_str()); if(TempGrf == NULL ) return true; Grf = SDL_DisplayFormat(TempGrf); SDL_FreeSurface(TempGrf); if(Grf == NULL ) return true; SDL_SetColorKey(Grf, SDL_RLEACCEL | SDL_SRCCOLORKEY, SDL_MapRGB(Grf->format, Key.r, Key.g, Key.b)); Loaded = true; return false; } bool GrfImage::ImgLoad(string FName, SDL_Color Key) { ... EXTPANDED VERSION OF ABOVE THAT LOADS CLIPPING TOO... } bool GrfImage::ImgBlitBMP(short x, short y, SDL_Surface* Dest) { if (Loaded) { SDL_Rect Offset; Offset.x = x; Offset.y = y; if (SDL_BlitSurface(Grf, NULL, Dest, &Offset) == 0) return false; } return true; } bool GrfImage::ImgBlit(short x, short y, unsigned short i, SDL_Surface* Dest) { if ((Loaded) and (i < GrfClip.size()) and (GrfClipReg)) { SDL_Rect Offset; Offset.x = x; Offset.y = y; if (SDL_BlitSurface(Grf, &GrfClip, Dest, &Offset) == 0) return false; } return true; } I'd thought I'd covered all bases with this - the class should comprehensively manage any access to the SDL_Surface pointer, as well as safely copying the surface rather than just copying the pointer. But now if I have in my main program source file: vector<GrfImage> MyImg; while (MyImg.size() < 7) { GrfImage MyTempImg; MyTempImg.ImgLoadBMP("graphics.bmp", C_Red); // 'C_Red' is a predefined SDL_Color MyImg.push_back(MyTempImg); } ...I get a seg fault (The 7 is arbritrary, and the whole routine is technically pointless as it just loads the same BMP 7 times). At my wit's end, I tried: GrfImage MyImg[7]; int i = 0; while (i < 7) { GrfImage MyTempImg; MyTempImg.ImgLoadBMP("graphics.bmp", C_Red); MyImg = MyTempImg; i++; } ...And everything went fine. I also tried: GrfImage Img1; if(1) { GrfImage Img2; Img2.ImgLoadBMP("graphics.bmp", C_Red); Img1 = Img2; } Img1.ImgBlitBMP(0,0,Screen); ...And everything went fine too (this was to test that operator= was working as I thought, as Img2 should destruct when it goes out of scope, shouldn't it?) I'm metaphorically tearing my hair out over this one. Why can't I vectorise my class? What fundamental thing have I completely missed that is causing this?! Any pointers gratefully received. Ronnie
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!