Skip to main content
GameDev.net gamedev.net
🔒 Locked

Problem getting address memory in C++

Started by MajinMusashi Apr 26, 2005 at 9:52 AM 3 replies 1.6k views
Original Post
MajinMusashi
MajinMusashi
Hi! I'm having a little problem getting the address memory of an array of floats. Take a look at the code:

// Simple text object
class C_TextSimple : public C_TextBase {
private:
	GLuint listBase;
	float* charWidth;
};

C_TextSimple::C_TextSimple( const char* fontName, int size ) {
	listBase = BuildFont( fontName, size , charWidth );		// charWidth = 0xbaadf00d
}


// Font object
class C_TextFont {
private:
	float charWidth[128];
public:
	float* getWidths();
};

float* C_TextFont::getWidths() {
	return charWidth;
}


// Text manager singleton
#define BuildFont C_TextManager::getInstance().buildFont

class C_TextManager {
private:
public:
	unsigned int buildFont( const char*, int, float* );	// Build font
};

unsigned int C_TextManager::buildFont( const char* fontName, int fontHeight, float* charWidth ) {
	C_TextFont newFont( library, fontName, fontHeight );
	fontVector.push_back( newFont ); 
	charWidth = fontVector.back().getWidths();	// charWidth = 0x014085f0 (OK, it is what I want)
	...
}

As you can see, C_TextSimple ctor calls C_TextManager's BuildFont, passing the charWidth pointer (and I want it to point at C_TextFont's array of widths). Inside C_TextManager::buildFont, charWidth receives the correct array address (0x014085f0), but when the execution flow returns to C_TextSimple ctor, charWidth is reseted again to its initial address (0xbaadf00d). Can you point me what's wrong? Thanks (and sorry for the bad English)!!!
ToohrVyk
ToohrVyk
You are passing the pointer by value, so changing it will not change the value of the original pointer back in the constructor.

You need to pass the pointer by reference:
BuildFont( .. , .. , float* & charWidth )
Pseudo
Pseudo
try a double pointer.

ie.
float** charWidth
MobileOak
MobileOak
When you pass in a pointer to a function, that allows you to modify the data that it is pointing to, but not the actual pointer itself. It's like doing this:

void foo(){  int myInt = 3;  bar(myInt);  cout << myInt;}void bar(int myInt){  myInt = 5;}


and expecting the output to be 5. Unless you're passing by reference, or passing a pointer to the data you want to modify, you're only manipulating a copy of the data.

Try:
unsigned int C_TextManager::buildFont(const char * fontName, int fontHeight, float **charWidth) {  ...  (*charWidth) = fontVector.back().getWidths();}


I *think* that's right, but I haven't compiled it.
Zahlman
Zahlman
In C++, this is better accomplished by passing by reference.

Also, consider the possibility that this singleton setup is not what you're looking for. Especially because you're calling it a "manager". As the old (?) joke goes, since classes are supposed to be named according to what they do, classes named "manager" take all the credit and add little value to the system. :)

// "Management" done inside TextBase:class TextBase {  private:  // static stuff needed for buildFont  protected:  static unsigned int buildFont(const std::string& fontName, int fontHeight, float*& charWidth ) {    TextFont newFont( library, fontName.c_str(), fontHeight );    fontVector.push_back( newFont );     charWidth = newFont.getWidths();	  } // etc.}// TextSimple ctor:TextSimple::TextSimple( const char* fontName, int size ) : listBase(buildFont(fontName, size)) {}


Of course, there's also the option of having client code not construct objects directly, but instead applying some sort of factory pattern:

// "Management" done inside TextBase:class TextBase {  private:  // static stuff needed for factory  public:  // Factory method which returns a TextSimple object.  // You can expand on this concept... client code might not even have to know  // the exact type of object returned, just that it is some kind of TextBase.  // And we take in the name and height parameters that were offered:  static TextSimple buildFont(const std::string& fontName, int fontHeight) {    TextFont newFont( library, fontName.c_str(), fontHeight );    fontVector.push_back( newFont );     float * charWidth = newFont.getWidths();    // etc.; then actually make the font:    int listBase = whatever_we_were_returning_before();    return TextSimple(listBase, charWidth);  } // etc.}// TextSimple ctor now takes exactly the parameters it needs:TextSimple::TextSimple(GLuint listBase, float* charWidth) : listBase(listBase), charWidth(charWidth) {}// You can privatize this ctor as desired, and possibly make TextBase a friend, // or something... you might be able to do the trick by just being careful about// what classes are mentioned in which headers ;)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.