Jump to content
  • Advertisement
Sign in to follow this  
ajm113

Why Do I Lose Data In a Char Pointer When Passed Into or Over a Function?

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

Hello, I'm writing a library using low level C++ methods so my library can easily be built in C. So I'm staying away from C++ standard templates. So vectors and strings are a bit limit. (Plus I think it's fun to have a bit of a challenge. ;) ). I've mostly been using strings in C++ for ease of use, and I decided to stick with char pointers, but I appear to run into odd problems, of which I cant explain.. I'll give a example.

//Issue One

char buffer[MAX_LENGTH];
sprintf_s(buffer, MAX_LENGTH, "Hello World!")

const char* bufferP = doLogic(buffer);

//bufferP = "Goodbye World!" after doLogic


//Some random function in my class that has nothing to do with bufferP at all.
doMoreMath();

//Wut? Now bufferP equals random garbage data?
//bufferP = "/////////tx///"

I know this problem can be fixed doing this:

const char* bufferP = doLogin();

char buffer_a[MAX_NAME_LENGTH];
memset(buffer_a, 0, MAX_NAME_LENGTH);
strncpy(buffer_a, bufferP, strlen(bufferP));

But why does this happen? This issue never seems to happen on any other pointers I've created, like objects. Is it necessary I do everything in char arrays? So I don't lose data randomly?

 

Thank you, Andrew.

Edited by ajm113

Share this post


Link to post
Share on other sites
Advertisement
it's hard to tell since you didn't give an actual working example, but my guess is your returning stack memory from doLogic, and when you call doMoreMath that stack memory is being overwritten, because you never should return stack allocated memory.

Share this post


Link to post
Share on other sites

What do your doLogic and doMoreMath do? (too many 'do's!)

 

In particular, what exactly are you returning from doLogic? If you're creating a buffer with local scope in doLogic and returning a pointer to it, you're only ever going to get nonsense back.

 

ph34r.png

Edited by mark ds

Share this post


Link to post
Share on other sites

Ah, that would make sense. So I need to make the memory heap then so I can use the variable globally. I didn't think I would need a working example since I thought putting comments of the output would be enough. I really need to get back to the basics again, but at lower level.

 

@Mark

 

DoLogic is anything that returns char*. I.E

 

Example of a substr function I made:

char* awesome_ini::aw_subStr(const char* line, size_t start, size_t length)
{
	char subbuff[AWI_MAX_KEY_NAME_LENGTH];

	memset(subbuff, 0, AWI_MAX_KEY_NAME_LENGTH);

	size_t p = 0;
	for (size_t i = start; i < length+1; i++)
	{
		subbuff[p] = line[i];
		p++;
	}

return (char*)subbuff;
}

That also causes the pointer in the example code to go away after a few lines of code. And do math is simply a function that does anything really...

 

I.E

void doMath(void)
{
//Do some long calculation
int x = 5 - 2;
printf("%i\n", x);
}

Share this post


Link to post
Share on other sites

A better way would be

char srcBuffer[MAX_LENGTH]
sprint_s(srcBuffer, MAX_LENGTH, "Hello World!");

char dstBuffer[MAX_LENGTH]

bool errorVal = doLogic(srcBuffer, dstBuffer); // return false if dstBuffer is too short

Share this post


Link to post
Share on other sites

 

A better way would be

char srcBuffer[MAX_LENGTH]
sprint_s(srcBuffer, MAX_LENGTH, "Hello World!");

char dstBuffer[MAX_LENGTH]

bool errorVal = doLogic(srcBuffer, dstBuffer); // return false if dstBuffer is too short

 

That is certainly the "C" way of doing things and it sounds like this is what the OP's goal is.

Share this post


Link to post
Share on other sites

Yes, a very common C idiom is to avoid allocation but instead to pass a buffer to a pre-allocated (possibly uninitialised) buffer / structure of sufficient size. In some cases, a library will have a function for determining the size of a buffer that needs to be passed when this would not be known.

Share this post


Link to post
Share on other sites

A better way would be

char srcBuffer[MAX_LENGTH]
sprint_s(srcBuffer, MAX_LENGTH, "Hello World!");

char dstBuffer[MAX_LENGTH]

bool errorVal = doLogic(srcBuffer, dstBuffer); // return false if dstBuffer is too short


`doLogic' should also take an argument that is the length of `dstBuffer', so it can make sure to not write past the end of the buffer. Notice how `sprint_s' already does that.

Share this post


Link to post
Share on other sites

 

A better way would be

char srcBuffer[MAX_LENGTH]
sprint_s(srcBuffer, MAX_LENGTH, "Hello World!");

char dstBuffer[MAX_LENGTH]

bool errorVal = doLogic(srcBuffer, dstBuffer); // return false if dstBuffer is too short

`doLogic' should also take an argument that is the length of `dstBuffer', so it can make sure to not write past the end of the buffer. Notice how `sprint_s' already does that.

 

To be even safer, it should take the length of srcBuffer as well

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!