Sign in to follow this  
Garlin

sprintf not working in Release build

Recommended Posts

Garlin    122
Hey Guys Perhaps someone can help me. My app is running fine in Debug mode but in Release it seems as though any sprintf_s/wsprintf_s functions are not working. The buffers are all allocated properly, but sprintf is coping rubbish data into the buffer. Any ideas? I'm using VS2005. Code is nothing complex... char test[256]; memset(test, 0, 256); sprintf_s(test, "%s testtext", "text"); 'test' after that is rubbish. It also seems as though it has something to to with optimizations. If I disable optimizations or change it to Minimize Size then it seems to work. But it doesn't work all the time. What could be going wrong there?

Share this post


Link to post
Share on other sites
Cambo_frog    855
You say sprintf in your title, but use sprintf_s in your code.

Have you posted your actual code, 'cause the second parameter to sprintf_s should be of type size_t representing the size of the buffer.

see here.

Share this post


Link to post
Share on other sites
Garlin    122
Yeah I kw. The thing is it's with any *printf* functions I use. I've actually got it working when I disable optimzations.

The problem I'm having now is that I'm using '_vstprintf' with an argument list (va_list), and it's also not working correctly. I'm sure they are related.

Share this post


Link to post
Share on other sites
CTar    1134
Quote:
Original post by Garlin
Yeah I kw. The thing is it's with any *printf* functions I use. I've actually got it working when I disable optimzations.

The problem I'm having now is that I'm using '_vstprintf' with an argument list (va_list), and it's also not working correctly. I'm sure they are related.


Post your actual code (as Cambo_frog said). Both
char test[256];
memset(test,0,256);
sprintf_s(test,256,"%s testtext", "text");

and
char test[256];
memset(test,0,256);
sprintf(test,"%s testtext", "text");

Works fine for me in VS05 with optimizations turned on, so it isn't as simple as the snippet you posted, we need context.

Share this post


Link to post
Share on other sites
legalize    116
Quote:
Original post by hlsl
Move "char test[256];" to header(ie make it static) and declare it like "char test[MAX_PATH];"


No, don't do this. This will define test in any source file that includes this header and then you'll have multiply defined symbols for test. Also, I don't see why declaring it of size MAX_PATH is relevant here; from the examples shown, its not a file path.

Generally, I don't use C style char arrays (I use std::string) or printf style functions in C++ because they aren't type safe. I'll use C++ iostreams or boost::format if I am converting legacy printf-style code to C++.

Both C style char arrays and printf-style functions are the constant source of complex and difficult to find errors in C++ applications. Avoid both of them.

[Edited by - legalize on August 10, 2008 4:52:19 PM]

Share this post


Link to post
Share on other sites
rip-off    10976
Quote:
Original post by hlsl
Move "char test[256];" to header(ie make it static) and declare it like "char test[MAX_PATH];"


Please explain why you would do either of those things.

Share this post


Link to post
Share on other sites
hlsl    100
Quote:
Original post by legalize
Quote:
Original post by hlsl
Move "char test[256];" to header(ie make it static) and declare it like "char test[MAX_PATH];"


No, don't do this. This will define test in any source file that includes this header and then you'll have multiply defined symbols for test. Also, I don't see why declaring it of size MAX_PATH is relevant here; from the examples shown, its not a file path.

Generally, I don't use C style char arrays (I use std::string) or printf style functions in C++ because they aren't type safe. I'll use C++ iostreams or boost::format if I am converting legacy printf-style code to C++.

Both C style char arrays and printf-style functions are the constant source of complex and difficult to find errors in C++ applications. Avoid both of them.


I'm sorry for my unexplained post. I meant to move it to class members for example. The same thing happend to me recently and I was just describing the way I solved it so topic poster could try if it fixes his problem. I'm not saying it is the right way to solve problem, just the way it worked for me.

Share this post


Link to post
Share on other sites
Garlin    122
Moving it won't make a difference.

I exported debug information in the release build plus I used a message box to test it and plus my app crashes in release, and it's because the string being created is invalid.

I even created a new VS2005 Win32 project, put that code in that you see there, and it doesn't work in release.

I tried the same thing on VS2008 at my work and it worked fine. So I am really confused.

Share this post


Link to post
Share on other sites
Kitt3n    468
Often made mistakes:

std::string test;
sprintf (str, "%d", "test"); // crash, expected int, got a string
sprintf (str, "%s", test); // crash - expected c-string, got stl-string
sprintf (str, "%s", test.c_str()); // correct way

Also, MS added 'safe' (nonstandard extensions to sprintf, sprintf_s).
I think they take an additional parameters (not sure, I always use
the standard compliant ones)

sprintf_s(test, sizeof(test), "%s testtext", "text");
<= again, not sure if it takes the size (and I'm too lazy to look it up)

In general: Count the parameters (if there are multiple) and
make sure their types match.
Debug is usually very forgiving, but these things 'explode'
in release-builds (we made the tooltips for sacred 1 like that,
and I ended up testing every single one in release to make sure
there were no crashes because of nonmatching/missing params :)

Share this post


Link to post
Share on other sites
hlsl    100
Quote:
Original post by Kitt3n
Also, MS added 'safe' (nonstandard extensions to sprintf, sprintf_s).
I think they take an additional parameters (not sure, I always use
the standard compliant ones)


sprintf_s uses the same parameters as sprintf. It's snprintf which takes additional parameter ;)

Share this post


Link to post
Share on other sites
Lajnold    226
Quote:
Original post by hlsl
sprintf_s uses the same parameters as sprintf. It's snprintf which takes additional parameter ;)


snprintf and sprintf_s takes the same arguments (which is one more than what sprintf takes).

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