Jump to content
  • Advertisement
Sign in to follow this  
MajinMusashi

Problem getting address memory in C++

This topic is 4808 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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)!!!

Share this post


Link to post
Share on other sites
Advertisement
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 )

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 ;)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

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

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!