[RESOLVED] Access Violation During String Formatting
I get the following message when debugging my app:
Unhandled exception at 0x0043907e in Temporal.exe: 0xC0000005:
Access violation reading location 0xcccccccc.
This is the function causing the problem:
string GetString(uint resId, ...) {
string str = new Char[255];
int len = (int)wcslen(str);
LoadString(hMainInst, resId, str, len);
va_list argptr;
string msg;
va_start(argptr, str);
len = _vscwprintf(str, argptr) + 2;
msg = new Char[len];
vswprintf_s(msg, len, str, argptr);
va_end(argptr);
return msg;
}
The types used are defined as follows:
typedef wchar_t Char; // Char
typedef Char* string; // String
typedef unsigned int uint; // UInt32
The function works when it doesn't have to format the string, but when it does i get this exception. The string contains %s.
What's going on? Why is this happening?
Thanks,
Skoobie Du
[977 byte] By [
SkoobieDu] at [2007-11-20 11:39:55]

# 1 Re: [RESOLVED] Access Violation During String Formatting
Try:string GetString(uint resId, ...) {
string str = new Char[255];
int len = 255;
if(LoadStringW(hMainInst, resId, str, len) > 0)
{
...
# 2 Re: [RESOLVED] Access Violation During String Formatting
Ok, yeah, totally forgot about the leaks.
No, string is not from the STL.
I defined string as follows:
typedef wchar_t Char;
typedef Char* string;
The compiler is setup to use unicode, so LoadString is automatically changed to LoadStringW.
I changed the function slightly:
string GetString(uint resId, ...) {
string str = new Char[255];
LoadString(hMainInst, resId, str, 255);
va_list argptr;
string msg;
va_start(argptr, str);
int len = _vscwprintf(str, argptr) + 2;
msg = new Char[len];
vswprintf_s(msg, len, str, argptr);
va_end(argptr);
delete str;
return msg;
}
And, if it's possible to delete msg; after the return, then let me know. Like I said, it fails when trying to parse format specifications. If the format string doesn't contain format specifications, then it works.
This is the string that is causing the problem:
"Quit %s"
And the argument is:
"Temporal"
Logic says that there shouldn't be a problem, but there seems to be, or else I wouldn't be needing help.
Thanks for the fast replies so far.
# 3 Re: [RESOLVED] Access Violation During String Formatting
Here's the debugger info:
output.c - Line 1629
-------
Call Stack:
> Temporal.exe!_woutput_l(_iobuf * stream=0x0012f25c, const wchar_t * format=0x00396d3e, localeinfo_struct * plocinfo=0x00000000, char * argptr=0x0012f3cc) Line 1629 + 0x1f bytes C++
Temporal.exe!_vscwprintf_helper(int (_iobuf *, const wchar_t *, localeinfo_struct *, char *)* outfn=0x00432586, const wchar_t * format=0x00396d30, localeinfo_struct * plocinfo=0x00000000, char * ap=0x0012f3c8) Line 441 + 0x13 bytes C
Temporal.exe!_vscwprintf(const wchar_t * format=0x00396d30, char * ap=0x0012f3c8) Line 450 + 0x14 bytes C
Temporal.exe!GetString(unsigned int resId=2, ...) Line 25 + 0xd bytes C++
Temporal.exe!WndProc(HWND__ * hWnd=0x00080b90, unsigned int msg=16, unsigned int wParam=0, long lParam=0) Line 72 + 0x14 bytes C++
...
If any of that helps.
# 4 Re: [RESOLVED] Access Violation During String Formatting
1. What line of your code causes the "Access violation"?
2. Is your project a UNICODE one? If not - try to use LoadStringW instead of LoadString.
3. msg = new Char[len];
vswprintf_s(msg, len, str, argptr);
In this code snippet the len is the number of wide characters. What value must be passed to the vswprintf_s: the buffer size in "wide characters" or the buffer size in bytes? If the latter - multiply len by 2.
# 5 Re: [RESOLVED] Access Violation During String Formatting
Fixed the problem, sort of. I decided to separate the loading and formatting.
string GetString(uint resId) {
string buffer = new Char[255];
LoadString(hMainInst, resId, buffer, 255);
return buffer;
}
string FormatString(string format, ...) {
va_list args;
string buffer;
va_start(args, format);
int len = _vscwprintf(format, args) + 1;
buffer = new Char[len];
vswprintf_s(buffer, len, format, args);
va_end(args);
return buffer;
}
It isn't the most graceful solution, but it works. Now, when I want to format a resource string, I do this:
FormatString(GetString(someId), someArgs...)
I figure it had something to do with the contents of the strings. And for the final time it had nothing to do with the functions I was using. Those were all working in wide character mode. The string type I'm using is not the STL one. The STL, in my mind, is broken. I'm a .NET programmer, and I'm used to certain practices and methods. I'm programming in C++ (without .NET) because I don't necessarily need the .NET Framework for what I'm working on. I'm rambling, and so I will shut up now. I'd like to thank VictorN for trying to help. The thought is what counts. Thanks.
# 6 Re: [RESOLVED] Access Violation During String Formatting
The string type I'm using is not the STL one. The STL, in my mind, is broken.How is it broken, "in your mind"? I'm a .NET programmer, and I'm used to certain practices and methods.Including introducing memory leaks?
FormatString(GetString(someId), someArgs...)
So who gets to delete[] the buffer returned from GetString()? And how do you know that the first argument to FormatString will be a dynamically allocated char buffer, so that you know if you should call delete[] or not? As a matter of fact, none of the code you posted shows any memory cleanup.
I'm programming in C++ (without .NET) And in C++, when you use new[], you must use delete[], or a memory leak shows up.
If you didn't like std::string, then you could (should) have coded your own string class that handles memory properly, instead of passing off dynamically allocated memory around and not know who, what, when, or where the memory cleanup is done.
Before disparaging things that have been well-tested (the std::string and std::wstring classes), make sure that your own code is bullet-proof (which given what you posted, it isn't).
Regards,
Paul McKenzie
