Weird issue losing characters from std::string

Started by
14 comments, last by Paradigm Shifter 10 years, 7 months ago

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";
	}
Advertisement

Why are you snipping the stuff we need to see?

Please provide the actual code required to reproduce the problem.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

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.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

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";
    }

}

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"

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)
{
}

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?

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

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?

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.

This topic is closed to new replies.

Advertisement