Sign in to follow this  
Dragonion

A peculiar problem ...

Recommended Posts

Hi

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

[code]
char buffer[24];
sprintf_s(buffer,24,"Year=%f",2011);
[/code]
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 [i]this[/i] code:

[code]
char buffer[24];
sprintf_s(buffer,24,"Year=%f",2011);
[/code]
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 [i]first[/i] lines of code are executed in the main thread (the program) while the second ones are executed in a DLL procedure called [i]by[/i] 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 [i]is[/i] loaded in both the program and in the DLL.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
[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.
[/quote]
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 [code]sprintf_s(buffer,24,"hello");[/code] it still crashes :-/

Share this post


Link to post
Share on other sites
[quote name='Dragonion' timestamp='1313359699' post='4849138']
[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.
[/quote]
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 [code]sprintf_s(buffer,24,"hello");[/code] 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.

Share this post


Link to post
Share on other sites
[color="#1C2837"] [/color][code]sprintf_s(buffer,24,"hello");[/code][color="#1C2837"] [/color]
This can’t crash by itself if you are sure the buffer is 24 characters.
[list=1][*]Ensure the DLL code is up-to-date. Rebuild-All. Make sure it is definitely the one being used by the host program.[*]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.[*]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 [b]not[/b] the source of the error.[/list]

L. Spiro

Share this post


Link to post
Share on other sites
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 ;)

Share this post


Link to post
Share on other sites
[quote name='Dragonion' timestamp='1313439743' post='4849539']
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 ;)
[/quote]

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

Share this post


Link to post
Share on other sites
[quote name='Telastyn' timestamp='1313440059' post='4849542']...and this (among other reasons) is why we don't recommend C or C++ for beginners.[/quote]
Hahaha! Yeah, 9 years of C/C++ apparently isn't enough to advance to the next level ;D

Share this post


Link to post
Share on other sites
[quote name='Dragonion' timestamp='1313439743' post='4849539']
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 ;)
[/quote]

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

Glad you found it.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this