Sign in to follow this  

Pointers

This topic is 4812 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

In my Vector class there is a method which sepose to return it as a string when i do this code
char *V2D::toString()
{
	char str[50];
	sprintf(&str[0],"(%f , %f)",x,y);
	
	return &str[0];
}

and use cout<<v.toString(); it outputs trash But when i use char *str= new char[50]
char *V2D::toString()
{
	char *str = new char[50];
	sprintf(str,"(%f , %f)",x,y);
	
	return str;
}

it works fine. I dont want to allocate a new string each time toString method is being used.

Share this post


Link to post
Share on other sites
In your toString function, create the char string as a static variable. Boom, done.

Only word of warning is if you try and store the returned string.

Since it will change everytime you call the function.

:)


Hope that helps,

Rigear

Share this post


Link to post
Share on other sites
The string you're allocating in the toString function is allocated on the stack meaning that it goes out of scope when the function returns. After this, there's no guarantee of it's contents (as it's memory is given back to the stack) so that explains why you're getting garbage.

One way of doing this would be to store a buffer in your vector class that's filled by the toString function and returned back; you could also declare the str buffer as static - however I doubt either of these methods are threadsafe (especially the second). Another (more preferred way) would be to pass a buffer (maybe std::string) to the toString function which is then filled by the function. This takes all the memory allocation away from the vector class and puts the owness clearly on the function calling the toString method.

Share this post


Link to post
Share on other sites
Hi!

The problem with your code is, that you return a pointer to a local variable (str). Your options are in this case to create a new string each time the method is called, or have a large enough string as a parameter which you can then write the string to. Like this:


void V2D::toString( char* str )
{
sprintf( str, "(%f, %f)", x, y );
}



The problem with this is, though, that you have to rely on a large enough buffer being passed to the function.

Hope that helps!

Cheers,
Drag0n

Share this post


Link to post
Share on other sites
Ohhh, how could i forgot :/ I must never return variables of function scopes. Thanks :)
And you are right I should allocate a buffer for each vector instance!

Share this post


Link to post
Share on other sites
Quote:
Original post by Drag0n
The problem with this is, though, that you have to rely on a large enough buffer being passed to the function.


I'd personally use a std::string in order to ensure such problems don't occur. In safe programming you should never assume that the buffer is big enough ;)

Share this post


Link to post
Share on other sites
Storing a buffer for every vector instance will escalate very very fast. I'd suggest using a private static buffer for the class. (or even better std::string! but I provide a char-array example to go with your first attempts)

class V2D
{
public:
...
private:
...
static char m_string[50]; // since 50 was the number you're using in your example, see note below
};

const char *V2D::toString()
{
sprintf(m_string,"(%f, %f)",x,y);
return &m_string;
}





Or something similar, haven't got the time to read it through for errors atm :) Why 50 size of the buffer though?
With regular floats you have 23 bits of mantissa, which equals a maximum of 7 significant digits. Add 2 for the "0." and you have 9 characters for each float.

Surely the buffer doesn't have to be larger than 23 characters? ( 9 per float + 5 for "(, )" + terminating null character? Or have I missed something? (probably have, am quite tired atm:)

Then again, it's better to have a slightly oversized buffer than a too small one :) (and it's only 27 bytes difference since you'll be storing it statically)

Do consider using std::string though, and you won't have to worry about the buffer size :)

Enough ranting from me :)

Share this post


Link to post
Share on other sites
Quote:
Original post by evolutional
Quote:
Original post by Drag0n
The problem with this is, though, that you have to rely on a large enough buffer being passed to the function.


I'd personally use a std::string in order to ensure such problems don't occur. In safe programming you should never assume that the buffer is big enough ;)


True, true, but I recall reading the thread title "Pointers". ;)

You're of course right, the standard library is part of the language and should be used. Especially in this case.

Cheers,
Drag0n

Share this post


Link to post
Share on other sites

This topic is 4812 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this