Jump to content
  • Advertisement
Sign in to follow this  
Burnt_Fyr

Weird issue losing characters from std::string

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

I just forked a program I'm working on, and recompiled the edited branch, and somehow am losing characters from a std::string passed as a parameter in a function.

ShipWrightLoader shl;
shl.Load("k800.txt", &sh);

when i get inside the function:

void ShipWright::ShipWrightLoader::Load(std::string filename, ShipHull* sh)
{
// function body
}

the filename is truncated to ".txt"

I've tested with a longer filename, and it seems that the string is being split in 2, leaving just the last half of the characters. I'm suspecting some issue with MBS/unicode settings, but am lost as to where to begin the hunt. I should mention that the untouched branch still works just fine, and the forked branch was created by copying the entire solution, renaming the vc2010 project and solutions, and adding my graphics library that the new branch will use(previously it was based in GDI).

 

EDIT: after more testing it seems even more strange. In the load function, if file loading is unsuccessful a warning is sent to std::cout(redirected to a console window) and the warning prints out the correct filename, using the same parameter string passed into the function.

	// further down the load function
        if(success)
	{
		// snipped
		
	}
	else
	{
		std::cout << "Error opening file:" << filename  << "\n";
	}
Edited by Burnt_Fyr

Share this post


Link to post
Share on other sites
Advertisement

I didn't think the code was relevant, as in the OP the filename appeared to be corrupted being passed IN to the fuction. As well, it is still working AS IS on the unedited fork, so I assume it had something to do with a project setting. Also, it's hacky code that is used just to have a model to work with while i code features in the program. Anyways, I cleaned it up a bit down to the smallest chuck of code that will still display an error for me,and here it is:

void ShipWright::ShipWrightLoader::Load(std::string filename, ShipHull* sh)
{
    std::ifstream file;
    int major,minor,build,revision;
    file.open(filename, std::ifstream::in);
    
    if(file.good())
    {
        char Line[33];
        memset(Line,0,33);


        file.get(Line, 32);

        major = Line[16];
        minor = Line[20];
        build = Line[24];
        revision = Line[28];
    }
    
    else
    {
        std::cout << "Error opening file:" << filename  << "\n";
    }

}

Share this post


Link to post
Share on other sites

How do you determine the content of filename inside the function?

 

If a std::string contains a zero character anything that operates on char* will think it's truncated.

I almost upvoted this, but quickly realized that this is not the issue with the filename "abcgde.txt" which is truncated to "de.txt"

Share this post


Link to post
Share on other sites

Just a quick quess... well I don't think it is really that related to the problem, but do you get a different result if you pass in the string as const reference (which you should probably be doing anyway for performance reasons, though it may not be a difference here since a std::string is getting constructed anyway).

void ShipWright::ShipWrightLoader::Load(const std::string& filename, ShipHull* sh)
{
}

Share this post


Link to post
Share on other sites

I assume you did a full rebuild?

 

If so, put a breakpoint at the start of ShipWright::ShipWrightLoader::Load and inspect the content of filename in the debugger.

Does the size and content match what you expect?

Share this post


Link to post
Share on other sites

After a fresh pot of coffee, and some stepping, i found the issue, but would like clarification on what happened if possible. As i said before, the std::string appeared to be wrong from the outset, but later appears to be unscathed.

 

stepping into the construction of the std::string, i end up here:

//xstring
basic_string(const _Elem *_Ptr)
		: _Mybase()
		{	// construct from [_Ptr, <null>)
		_Tidy();
		assign(_Ptr);
		}

when I hit assign, i noticed this section of code:

	_Myt& assign(const _Elem *_Ptr, size_type _Count)
		{	// assign [_Ptr, _Ptr + _Count)
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (_Count != 0)
			_DEBUG_POINTER(_Ptr);
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */

		if (_Inside(_Ptr))
			return (assign(*this, _Ptr - _Myptr(), _Count));	// substring

		if (_Grow(_Count))
			{	// make room and assign new stuff
			_Traits::copy(_Myptr(), _Ptr, _Count);
			_Eos(_Count);
			}
		return (*this);
		}

My graphics library had iterator debug disabled, which was done in order to improve program speed while working on my old dirtbag computer. When i linked the graphics lib to this exe, i set the exe's iterator debugging to the same level so as to avoid the conflict during linking. Setting both the library project and the exe project to iter debug level 2 seems to have fixed the problem, and I have verified that this works during release mode as well. But I'm stumped as to why. Could someone with more experience shed some light?

Share this post


Link to post
Share on other sites

 

Just a quick quess... well I don't think it is really that related to the problem, but do you get a different result if you pass in the string as const reference (which you should probably be doing anyway for performance reasons, though it may not be a difference here since a std::string is getting constructed anyway).

void ShipWright::ShipWrightLoader::Load(const std::string& filename, ShipHull* sh)
{
}

As the issue was solved before i read this, i did not check. As a rule I strive for const correctness, but only on code that will see the light of day. This was quick code to get something loaded and was put together in about 10 minutes. It worked fine in the other branch, so I hadn't worried about it yet, assuming that I would deal with it during my next refactor. I always try to get something working first, then deconstruct and rebuild using the best practices i can.

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!