| | |
Vector problem
![]() |
I have a vector array of a class that's giving me some crap. I would beat it up, but that might result in some innocent circuits getting damaged.
Class:
Code:
The problem is that right after the if statement the class destructor is called. Oddly enough, when I use fonts[].font later, I don't get an error; I only get the access error after the program attempts to terminate, because it calls the destructor again. It goes something like this:
constructor
loads font
destructor
renders text - renders with a closed font??
back to main
display text - displays fine
destructor - error happens here
I can post the rest of the source code, if necessary. What stupid thing am I missing?
Class:
c++ Syntax (Toggle Plain Text)
class Font { public: Font(); ~Font(); int style; int ptSize; std::string name; TTF_Font *font; }; Font::Font() { style = TTF_STYLE_NORMAL; ptSize = 0; name = ""; font = NULL; } Font::~Font() { // Access violation TTF_CloseFont( font ); }
Code:
c++ Syntax (Toggle Plain Text)
std::vector<Font> fonts; SDL_Surface *renderText( std::string fontName, int ptSize, std::string text, const SDL_Color *textColor, const SDL_Color *backroundColor, int flags ) { // cut if( fontElement == -1 ) { std::string fileName = "c:\\windows\\fonts\\" + fontName; // class constructor called here fonts.resize( fonts.size() + 1 ); fontElement = fonts.size() - 1; fonts[ fontElement ].ptSize = ptSize; fonts[ fontElement ].name = fontName; fonts[ fontElement ].font = TTF_OpenFont( fileName.c_str(), ptSize ); if( fonts[ fontElement ].font == NULL ) { return NULL; } if( fontStyle != TTF_STYLE_NORMAL ) { fonts[ fontElement ].style = fontStyle; TTF_SetFontStyle( fonts[ fontElement ].font, fontStyle ); } // class destructor called here } // cut // no error here if( flags & FH_BLENDED ) { return TTF_RenderText_Blended( fonts[ fontElement ].font, text.c_str(), fgColor ); } else if( flags & FH_SHADED ) { return TTF_RenderText_Shaded( fonts[ fontElement ].font, text.c_str(), fgColor, bgColor ); } else if( flags & FH_SOLID ) { return TTF_RenderText_Solid( fonts[ fontElement ].font, text.c_str(), fgColor ); } return NULL; }
The problem is that right after the if statement the class destructor is called. Oddly enough, when I use fonts[].font later, I don't get an error; I only get the access error after the program attempts to terminate, because it calls the destructor again. It goes something like this:
constructor
loads font
destructor
renders text - renders with a closed font??
back to main
display text - displays fine
destructor - error happens here
I can post the rest of the source code, if necessary. What stupid thing am I missing?
•
•
Join Date: Oct 2007
Posts: 305
Reputation:
Solved Threads: 43
This is interesting. I have never really tried to insert elements into a vector in this fashion. I normally use the push_back() function to add values to the vector. I attempted to do what you are doing, and calling the resize() function calls the class constructor once and the destructor twice. And then the destructor is called once more when the main exits. Which would be very bad if you were using dynamically allocated elements in your class. I am not sure how this works internally, but is there a reason why you are using this logic instead of just adding elements to the vector using push_back() ?
C++ Syntax (Toggle Plain Text)
class myClass{ public: myClass(){cout << "myclass constructor" << endl;} ~myClass(){cout << "myclass destructor" << endl;} int number; }; int main () { vector<myClass> myVector; int element; myVector.resize(myVector.size() + 1); element = myVector.size() - 1; myVector[element].number = 100; myVector[element].number = 200; return 0; }
Last edited by stilllearning; Oct 9th, 2008 at 8:19 pm.
I used resize instead of push_back because push_back requires that you put in a value. If I were to declare another instance of Font, set all the variables, then use that in push_back(), it is my understanding that the pointers from both instances would point to the same object. Since the temporary class would call the destructor at the end of the if statement it would delete the object, leaving me with a dangling pointer. Alternatively, I could do:
It does work, but it just seems odd. Of course, I could be wrong cause I'm no expert on vector arrays.
c++ Syntax (Toggle Plain Text)
Font temp; fonts.push_back( temp );
•
•
Join Date: Oct 2007
Posts: 305
Reputation:
Solved Threads: 43
If you wanted to you could use a vector of pointers instead of objects. That way you can create a new object as you needed it and add it to your vector. And then delete them all at the end.
C++ Syntax (Toggle Plain Text)
vector<myClass*> myVector; myClass *tmp; for(unsigned int i = 0; i < 5; i++){ tmp = new myClass(i); myVector.push_back(tmp); } // do stuff // delete any allocated pointers for (unsigned int i = 0; i < myVector.size(); i++){ delete myVector[i]; }
Last edited by stilllearning; Oct 9th, 2008 at 9:12 pm.
The problem with that approach is how my function works. Each time the program needs to display text, it calls renderText(). Loading a font takes my computer about 3 milliseconds, and I'm already worried about SDL going too slow. Thus, I opted to use a vector array of class 'Font', since vectors are easiest when it comes to expanding arrays, and each class can automatically close the TTF_Font* variable, plus I can use previously loaded fonts and I could do it all without the hassle of dynamic memory. Since no other function has access to the vector, I can't delete the class pointers in the vector at the end of the program.
Your response did get me thinking about some possible alternatives. I could make another flag to put in the flags parameter that would let the function know it has to delete the fonts; I could make a class which would contain the vector of pointers to the 'Font' class, making use of the class destructor to delete the vector; or I could give a void function access to the vector, so I could use atexit() to delete the vector (probably wouldn't work as the vector would probably be removed from memory prior to the atexit() call).
If you have any other ideas, please let me know, as mine kinda suck. I would still like to know why the vector is acting as it is, so I can avoid this in the future.
Your response did get me thinking about some possible alternatives. I could make another flag to put in the flags parameter that would let the function know it has to delete the fonts; I could make a class which would contain the vector of pointers to the 'Font' class, making use of the class destructor to delete the vector; or I could give a void function access to the vector, so I could use atexit() to delete the vector (probably wouldn't work as the vector would probably be removed from memory prior to the atexit() call).
If you have any other ideas, please let me know, as mine kinda suck. I would still like to know why the vector is acting as it is, so I can avoid this in the future.
Well, I messed around with my code for a few hours, and I discovered that it wasn't actually a problem with the vector (as always, I blamed the other code first). The problem is by the time the program gets to the Font destructor, the TTF library has already quit. This is really quite annoying, since I closed the TTF library using atexit().
The problem now is getting the class destructor to run before the atexit stuff. With the code:
the output will be "Constructor Func Destructor". Does anybody know a [non-messy] way around this?
The problem now is getting the class destructor to run before the atexit stuff. With the code:
c++ Syntax (Toggle Plain Text)
#include <iostream> using namespace std; class myClass { public: myClass() { cout << "Constructor" << endl; } ~myClass() { cout << "Destructor" << endl; } }; myClass loser; void func() { cout << "Func" << endl; } int main() { atexit( func ); return 1; }
![]() |
Similar Threads
- help vector problem (C++)
- strstream problem (C++)
- save self-defined object in vector problem (C++)
- passing vector to a pointer? (C++)
Other Threads in the C++ Forum
- Previous Thread: Help on TCP Winsock
- Next Thread: Simple manipulation help needed.
| Thread Tools | Search this Thread |
api array based binary bitmap business c++ c/c++ char class classes code codesamplerunwhilecommands coding commentinghelp compile console conversion count decide delete deploy desktop developer directshow dll download dynamic dynamiccharacterarray email encryption error faq file forms fstream function functions game givemetehcodez graph guess gui hash homeworkhelp homeworkhelper iamthwee ifpug ifstream incrementoperators infinite input int integer java lib linkedlist linker listing loop looping loops map math matrix memory multiple news node output pointer port problem proficiency program programming project python random read recursion reference rpg string strings temperature template test text text-file tree url variable vector video win32 windows winsock wordfrequency wxwidgets





