Question

Hey everyone, I am getting a heap corruption error I cannot figure out.

char * c = (char *) malloc(1);
// main loop
_gcvt_s(c, 100, ball->get_X_Direction(), 10);
      if(pushFont(c, (SCREEN_WIDTH - 30), (SCREEN_HEIGHT - 40), message, screen,
font, textColor) == false)
      {
           //return 1; // error rendering text.
      }
// end main loop
free(c);

The above code is the only time I use c pointer, in _gcvt_s and pushFont() which simply accepts a char * as its first parameter, and puts the text on the screen. Other then that I do not use c. When I try to free c after the main loop (which I think I am supposed to do), I get an error saying Visual Studio has acquired an error with the heap (heap corruption).

Commenting out the call to pushFont I still receive the error.

Can anyone explain to me why freeing a character (the 1 byte I allocated on the heap) would give me a heap corruption?

Lastly my main loop does a lot of stuff, a buddy and I are making a pong game with WinSocket, the rest of the main body is the loop for the game. I didnt think it was necessary to post, but I will update my post with the entire main loop if it is necessary, but I believe I am just off with my understanding of malloc() and free().

Thanks all,

Was it helpful?

Solution

Doesn't _gcvt_s use the 2nd parameter as the max size of the allocated buffer? You allocate 1 byte but tell _gcvt_s there are 100. So it happily writes up to 100 bytes into the buffer corrupting your heap. Then the free crashes. Allocate 100 bytes if you are going to potentially access 100 bytes.

EDIT: It sounds like you need to learn how C stores and manipulates strings. C stores strings as individual bytes in contiguous runs of memory followed by an extra character to indicate the end of the string. This extra character has an ASCII value of 0 (not the character '0' which is ASCII 48). So if you have a string like "HELLO", it takes 6 bytes to store - one for each of the 5 letters and the terminator.

In order for _gcvt_s() to return the value to your buffer, you need to include enough bytes for the conversion and the extra terminating byte. In the case of _gcvt_s(), you are asking for 10 characters of precision. But you also have to reserve room for the decimal point, the potential negative sign.

According to this [documentation](http://msdn.microsoft.com/en-us/library/a2a85fh5(VS.80).aspx), there is a #define in the headers for the maximum necessary size of the buffer: _CVTBUFSIZE. The example there should help you with this issue.

OTHER TIPS

According to the documentation I can find _gcvt_s() takes a buffer and the length of that buffer as the first two arguments.

errno_t _gcvt_s( 
   char *buffer,
   size_t sizeInBytes,
   double value,
   int digits 
);

Your malloc()ed buffer is 1 byte long, you tell _gcvt_s() it is 100 bytes long. I would start looking here.

Why do you need to use the heap? If all you need is space for 1 char can't you just use a local variable:

char c;
_gcvt_s(&c...

?

You need more than one byte to store a float. Allocate a more practical length than 1 byte...

You also really don't need the heap, try a (slightly oversized) 16-byte buffer and giving _gcvt_s the correct buffer length (instead of the magical 100 you are giving it). De-magic your constants whilst you are at it.

const unsigned int cuFloatStringLength = 16;
const unsigned int cuFloatStringPrecision = 10;

char c[cuFloatStringLength];

_gcvt_s( c, cuFloatStringLength, ball->get_X_Direction(), cuFloatStringPrecision );

The problem should then be gone.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top