wrote to memory after end of heap buffer error

Dec 6, 2011 at 5:18pm
Hi, I realize that such a problem has already been discussed many times out there as I have found many threads with such a title but even after looking into 10 different threads I still dont know why this is happening to me (but maybe I'm just missing some basic understanding?).

here's the funtcion where the error shows up:
1
2
3
4
5
6
7
8
9
10
void Packets::SetVar( char* varname, int varvalue )
{
	int size = (int)ceil((float)(varvalue/10))+1;
	char* buffer = new char[size];

	sprintf(buffer, "%i", varvalue);
	SetVar(varname, buffer);

	delete[] buffer;
}


when the function is called, size contains 1 and varvalue contains 2.
when he tries to delete buffer, the program crashes with the above mentioned error. here it is more detailed:

HEAP CORRUPTION DETECTED: after Normal block (#248) at 0x02887598.
CRT detected that the application wrote to memory after end of heap buffer.
(Press Retry to debug the application)

also here is buffer before sprintf is called:
- buffer 0x02437598 "Íýýýý««««««««þîþ"
51 'Í' char

and after sprintf:
- buffer 0x02437598 "2"
50 '2' char

he has no problem with deleting buffer when I skip the sprintf call so I guess it has something to do with that?

and also I suppose I have to use here delete[] rather than delete?
Last edited on Jan 7, 2012 at 10:19pm
Dec 6, 2011 at 5:27pm
Do you really need to exactly dimension buffer with size? Can't you just do

 
char buffer[50];


Then you can know the number of digits you have used by looking at the return value of sprintf.

EDIT: Oh, and BTW varvalue/10 gives 0 if varvalue is < 10. You should put float(varvalue)/10
Last edited on Dec 6, 2011 at 5:29pm
Dec 6, 2011 at 5:29pm
Wait, that compiles? You're passing a char* as int on line 7?
Dec 6, 2011 at 5:32pm
@Gaminic I was assuming it was a different function, or just a typo in copying the code.
Dec 6, 2011 at 5:35pm
Line 7 wasn't there before the edit to his post.
Dec 6, 2011 at 5:43pm
well tbh I'm not sure what the intention of the given array size was since this is actually not my code (also thx for the wrong cast info, didnt see that). but I guess it was to prevent cases where the array was not big enough?

anyway, with char buffer[50] it works again, here's the content after initalization:
- buffer 0x02217598 "ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍýýýý««««««««îþ" char *

and after sprintf
- buffer 0x02217598 "2" char *

but still shouldnt it work with my mentioned code?
I mean its basically this
1
2
3
4
5
6
7
8
9
void function( char* varname, int varvalue )
{
varvalue = 2;
	char* buffer = new char[1];

	sprintf(buffer, "%i", varvalue);

	delete[] buffer;
}

so he writes the integer of varvalue into the array but the size is the same or? and why does he have a problem with deleting it afterwards?

@Gaminic: yes there is another existing function with the same name,
SetVar( char* varname, const char *varvalue )
Last edited on Dec 6, 2011 at 5:43pm
Dec 6, 2011 at 5:48pm
I think it should have at least size==2 (one for the end of string, or whatv you call it)
Last edited on Dec 6, 2011 at 5:48pm
Dec 6, 2011 at 5:53pm
after a taking second look at it I believe the actual problem was the wrong cast. because after I corrected it, the array size is automatically 2 which he can delete properly.

however Im still curious why it doesnt work with an array size of one? is sprintf writing more than one char into the array? or is the integer using more than one char?

and even if it is, shouldnt there be a problem at sprintf because the array is too small?
Last edited on Dec 6, 2011 at 5:53pm
Dec 6, 2011 at 6:00pm
As I said, sprintf does write one extra character, which is the null-character (automatically appended at the end of every string), so, yes, it needs one extra character.
Dec 6, 2011 at 6:05pm
but I could still use sprintf(buffer, "%i", 2) without problems even though buffer was too small (size of 1). and buffer contained the proper content afterwards (as seen in my first post)...

anyway, thx for the quick help guys ;)
Last edited on Dec 6, 2011 at 6:05pm
Dec 6, 2011 at 6:18pm
The null character could overwrite existing memory and even cause a segfault, or the existing memory could be written and change the null character, then your output is nonsense after the 2
Last edited on Dec 6, 2011 at 6:18pm
Dec 6, 2011 at 6:25pm
Why don't you just use a std::stringstream ? Then you don't have to worry about memory allocation.
Topic archived. No new replies allowed.