A peculiar problem ...

Started by
7 comments, last by 21st Century Moose 12 years, 8 months ago
Hi

I have just encountered a rather non-trivial problem. First, look at this code:


char buffer[24];
sprintf_s(buffer,24,"Year=%f",2011);

This works beautifully! The string is copied nicely into the buffer as it is supposed to, and afterwards everything else continues smoothly.

Now, look at this code:


char buffer[24];
sprintf_s(buffer,24,"Year=%f",2011);

This is nothing less than a pure catastrophe! As soon as it is executed the program crashes, Windows pops up a message-box telling me that the program needs to close, and I am pretty sure that if it wasn't for Windows' Security Center it would erase my hard-drive as well.

The thing is that the first lines of code are executed in the main thread (the program) while the second ones are executed in a DLL procedure called by the main thread. Under different circumstances I would agree that two lines of code is not much to go on, but the essence of the problem can really be boiled down to why sprintf_s is causing the program to crash when invoked in a DLL procedure? (If you want to try it yourself first create a DLL file and export a function using sprintf_s. Then simply call the function from a test app to see the crash).

I have no idea what's causing this behavior so I am crossing my fingers one of you will be able to enlighten me.

PS1: I have also tried using std::stringstream/strings to solve the problem (converting a floating-point value to ASCII), but this solution crashed as well.
PS2: Floating-point support is loaded in both the program and in the DLL.
Advertisement
The only thing I can see that is wrong with the code you show is the format specifier and the value being passed. You pass an integer, but the format specifier is a floating point value. That, in itself, should just produce garbage output (it's undefined in theory, but in practice that is what you're likely to get), but the problem is that it's a double precision floating point value, and your integer is likely not the same size. Most likely you're passing a 4-byte integer and sprintf_s reads an 8-byte floating point value from where the values are passed. You need to ensure that the value passed is really a double precision floating point value.

The only thing I can see that is wrong with the code you show is the format specifier and the value being passed. You pass an integer, but the format specifier is a floating point value. That, in itself, should just produce garbage output (it's undefined in theory, but in practice that is what you're likely to get), but the problem is that it's a double precision floating point value, and your integer is likely not the same size. Most likely you're passing a 4-byte integer and sprintf_s reads an 8-byte floating point value from where the values are passed. You need to ensure that the value passed is really a double precision floating point value.

I see you point, but 1) the constant is correctly converted to a double value in the program (in which there are no problems executing these lines), and 2) even if I omit the value and simply write sprintf_s(buffer,24,"hello"); it still crashes :-/

[quote name='Brother Bob' timestamp='1313359081' post='4849129']
The only thing I can see that is wrong with the code you show is the format specifier and the value being passed. You pass an integer, but the format specifier is a floating point value. That, in itself, should just produce garbage output (it's undefined in theory, but in practice that is what you're likely to get), but the problem is that it's a double precision floating point value, and your integer is likely not the same size. Most likely you're passing a 4-byte integer and sprintf_s reads an 8-byte floating point value from where the values are passed. You need to ensure that the value passed is really a double precision floating point value.

I see you point, but 1) the constant is correctly converted to a double value in the program (in which there are no problems executing these lines), and 2) even if I omit the value and simply write sprintf_s(buffer,24,"hello"); it still crashes :-/
[/quote]

Did you change the line in both the exe and the dll?

EDIT: Do you know for sure it crashes at that exact line? What tools are you using? Try using a debugger, the normal 'this program stopped working' can mean a whole range of things.
[color="#1C2837"] sprintf_s(buffer,24,"hello");[color="#1C2837"]
This can’t crash by itself if you are sure the buffer is 24 characters.
  1. Ensure the DLL code is up-to-date. Rebuild-All. Make sure it is definitely the one being used by the host program.
  2. Regardless of getting lucky the first time the code was called, either change %f to %u or change 2011 to 2011.0f. Having it work once is no justification for ever using %f with 2011.
  3. Make sure that really is the source of the error. Because if the DLL is up-to-date and the buffer is 24 characters long, that is not the source of the error.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Thanks for your feedback!

It turns out the crash occurred because I had forgotten to initialize a pointer in a constructor (which caused it to have some random value after afterwards). Oddly, this variable wasn't used anywhere near the place I call sprintf_s, but what the heck; if that's what it takes to make the boat float ;)

Thanks for your feedback!

It turns out the crash occurred because I had forgotten to initialize a pointer in a constructor (which caused it to have some random value after afterwards). Oddly, this variable wasn't used anywhere near the place I call sprintf_s, but what the heck; if that's what it takes to make the boat float ;)


...and this (among other reasons) is why we don't recommend C or C++ for beginners.
...and this (among other reasons) is why we don't recommend C or C++ for beginners.

Hahaha! Yeah, 9 years of C/C++ apparently isn't enough to advance to the next level ;D

Thanks for your feedback!

It turns out the crash occurred because I had forgotten to initialize a pointer in a constructor (which caused it to have some random value after afterwards). Oddly, this variable wasn't used anywhere near the place I call sprintf_s, but what the heck; if that's what it takes to make the boat float ;)


Yup, that's what stray pointers do. Always initializing everything is a good habit to get into.

Glad you found it.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

This topic is closed to new replies.

Advertisement