unknown cause of exception

Started by
11 comments, last by Zahlman 17 years, 11 months ago
I'm having a problem with one of my functions causing an exception but I can't figure out why. I've narrowed it down to one line in the function that calls another function so I'm not sure if the error is in the calling function or the function called.. this only happens when I run it straight from the folder and not within visual C 8. It also has different behavior when I run it straight from the folder but I don't know why.

void SerialGen()
{ 
	char alpha[80] ="ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";
	char* ppasswrd = NULL;
	wchar_t* wppasswrd = new wchar_t[11];
	char passwrd[80]="";
		
	int numChars = 20;
	
	for (int n=0; n<numChars; n++)
	{
		int x;
		x = 0 + int(35.0 * rand()/(RAND_MAX+1.0));
		passwrd[n]= alpha[x];
	}
	
	ppasswrd = passwrd;

	memset(wppasswrd,0,sizeof(wppasswrd));

	MultiByteToWideChar(  CP_ACP, NULL,ppasswrd, -1, wppasswrd,numChars );

	AddString(wppasswrd); // this is the line that causes an exception

	getchar();
	wppasswrd = NULL;
	delete[] wppasswrd;

}



here's the funtion called which works fine with passing TEXT("blah") to it but I don't know if it's causing the above problem when passing the wchar_t pointer.

STRINGSTRUCT* AddString(LPCWSTR StringToAdd)
{
	if(FirstString == NULL)
	{
		FirstString = new STRINGSTRUCT;
		LastString = FirstString;

		LastString->Next = NULL;
	}
	else
	{
		LastString->Next = new STRINGSTRUCT;

		LastString = LastString->Next;
		LastString->Next = NULL;
	}

	size_t len;

	LastString->DisplayString = StringToAdd;
	StringCchLength(StringToAdd, 512, &len);

	LastString->StringLength = len;

	return LastString;
}



can anyone help me out?
Artist 1st - Programmer 2nd(I'll get some material linked here sometime to support these claims, haha)
Advertisement
Looks like your wchar_t string is overwriting the boundary... one line BEFORE you say.

Your wchar_t array should at least be the same size as the password... and you're only allocating 11 for it.
my_life:          nop          jmp my_life
[ Keep track of your TDD cycle using "The Death Star" ] [ Verge Video Editor Support Forums ] [ Principles of Verg-o-nomics ] [ "t00t-orials" ]
well I was only allocating 11 for it cause it's 2 bytes and the password is only 20 chars long of 1 byte. for some reason if I make the wppasswrd anything other than 11 or 12 I get extra blank characters printed on screen with my password generated.
Artist 1st - Programmer 2nd(I'll get some material linked here sometime to support these claims, haha)
Quote:Original post by etsuja
well I was only allocating 11 for it cause it's 2 bytes and the password is only 20 chars long of 1 byte. for some reason if I make the wppasswrd anything other than 11 or 12 I get extra blank characters printed on screen with my password generated.


you need wchar_t[20] or larger... because MultiByteToWideChar() will write 20 wchar_t's into the array, which is 40 bytes.

You should probably make the array 21 wide chars long, and use ZeroMemory or memset to clear it first, too.

void SerialGen(){ 	char alpha[80] ="ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";	char* ppasswrd = NULL;	wchar_t* wppasswrd = new wchar_t[21];	char passwrd[80]="";			int numChars = 20;		for (int n=0; n<numChars; n++)	{		int x;		x = 0 + int(35.0 * rand()/(RAND_MAX+1.0));		passwrd[n]= alpha[x];	}		ppasswrd = passwrd;	memset(wppasswrd,0,sizeof(wppasswrd));	MultiByteToWideChar(  CP_ACP, NULL,ppasswrd, -1, wppasswrd,numChars );	AddString(wppasswrd); // this is the line that causes an exception	getchar();         // whoa! and the following will leak memory//	wppasswrd = NULL;//	delete[] wppasswrd;//      do this instead	delete[] wppasswrd;	wppasswrd = NULL;}
my_life:          nop          jmp my_life
[ Keep track of your TDD cycle using "The Death Star" ] [ Verge Video Editor Support Forums ] [ Principles of Verg-o-nomics ] [ "t00t-orials" ]
I set the length to 21 and I tried using zeromemory and memset but it prints the password with this after it when running from VC8 |||||||| and ||| when running from the folder. And I don't think I can use delete[] on it cause it clears the password. I don't know where I can deallocate it unless I make it global. maybe I could return it and then delete it outside the function? When it's 21 I don't get that exception though.

EDIT: nevermind I just figured out why it was doint it I changed
MultiByteToWideChar( CP_ACP, NULL,ppasswrd, -1, wppasswrd,numChars )
to
MultiByteToWideChar( CP_ACP, NULL,ppasswrd, -1, wppasswrd,(numChars + 1) )
Artist 1st - Programmer 2nd(I'll get some material linked here sometime to support these claims, haha)
Quote:Original post by etsuja
I set the length to 21 and I tried using zeromemory and memset but it prints the password with this after it when running from VC8 |||||||| and ||| when running from the folder. And I don't think I can use delete[] on it cause it clears the password. I don't know where I can deallocate it unless I make it global. maybe I could return it and then delete it outside the function? When it's 21 I don't get that exception though.


memset(wppasswrd,0,sizeof(wchar_t) * 21);

And if you don't want to clear the password... then don't delete wppassword
[smile]

Just remember to delete the array somewhere... keep a pointer to the wchar_t array in your struct, or something, and then delete it when your STRINGSTRUCT is deleted... perhaps in the destructor.

my_life:          nop          jmp my_life
[ Keep track of your TDD cycle using "The Death Star" ] [ Verge Video Editor Support Forums ] [ Principles of Verg-o-nomics ] [ "t00t-orials" ]
wait if DisplayString in my struct = StringToAdd and wppasswrd is getting passed to AddString isn't it already getting deleted when I delete my struct?
Artist 1st - Programmer 2nd(I'll get some material linked here sometime to support these claims, haha)
Quote:Original post by etsuja
wait if DisplayString in my struct = StringToAdd and wppasswrd is getting passed to AddString isn't it already getting deleted when I delete my struct?


Not unless you have explicit code in your struct's destructor to take care of those. You'll have memory leaks unless you call "delete" for everything you've called "new" for, and "delete[]" for everything you've called "new[]" for.

// delete FirstString calls...STRINGSTRUCT::~STRINGSTRUCT(){// you have to iterate through your linked list, and delete// all "DisplayString" like this// delete[] Next->DisplayString;// THEN You have to iterate through, deleting all "Next"... which might// blow the stack, if your linked list is very long (delete Next; would// recursively call the destructor STRINGSTRUCT::~STRINGSTRUCT())}


This is where smart pointers can really help you... with the "Next" pointers. If you declared "Next" a smart pointer in your struct, instead of just "STRINGSTRUCT *Next", it would mean you'd only have to explicitly go through and delete[] Next->DisplayString.

You'd no longer have to call "delete Next" in the destructor, and potentially blow the stack with a long linked list.

boost::shared_ptr and Loki::SmartPtr are good places to start.
my_life:          nop          jmp my_life
[ Keep track of your TDD cycle using "The Death Star" ] [ Verge Video Editor Support Forums ] [ Principles of Verg-o-nomics ] [ "t00t-orials" ]
Well I tried this and got an assertion failure:

void DeleteAllStrings(){	STRINGSTRUCT* ThisString = FirstString;	STRINGSTRUCT* DeadString = NULL;		while(ThisString != NULL)	{		DeadString = ThisString;		delete[] DeadString->DisplayString;		ThisString = ThisString->Next;		delete DeadString;	}	FirstString = NULL;	LastString = NULL;}


I also tried regular delete too
Artist 1st - Programmer 2nd(I'll get some material linked here sometime to support these claims, haha)
That code looks fine (to me)

When does it assert? Have you single-stepped through?

Does it assert on the first delete[], the first delete, or after everything is deleted?

Are there any other deletes or delete[]s in your code?
my_life:          nop          jmp my_life
[ Keep track of your TDD cycle using "The Death Star" ] [ Verge Video Editor Support Forums ] [ Principles of Verg-o-nomics ] [ "t00t-orials" ]

This topic is closed to new replies.

Advertisement