Click here to Skip to main content
15,903,175 members
Please Sign up or sign in to vote.
5.00/5 (2 votes)
See more:
Upgraded to the Community Edition, 2015, and my program blew up in release mode, but not debug mode. After painful debugging, found the culprit. The code worked fine in both modes in VS 2013 community edition. What stupid thing am I overlooking that explains the blowup? It is a Unicode program, and this section only changes a string to upper case.

C++
template <class T> T toUpper(const T & str) {
   T temp = str;
   std::transform(temp.begin(), temp.end(), temp.begin(), _toupper);  //BLOWS UP HERE
   return temp;
   }


Thanks,
David

Per CHill60's question, the error is: "Error: Access violation at 0x0009A7FC (tried to write to 0x0009A7FC), program terminated. Last CP is 'RF'."

So it is not allowing the program to rewrite the memory locations in release mode during the std::transform call. Why isn't debug mode affected?

What I have tried:

I eliminated the problem by changing the calling code to "if x==AAA or x=aaa then ...", but I'd like to understand why this code block didn't work.
Posted
Updated 2-May-16 10:35am
v2
Comments
CHill60 2-May-16 7:51am    
When you say "blows up" and "didn't work" what error message do you get?
Have you seen this post ... string - C++ std::transform() and toupper() ..why does this fail? - Stack Overflow[^]
David O'Neil 2-May-16 8:08am    
I've updated the question with error code info. As you will see, it is simply refusing to let my program rewrite the memory locations in the std::transform call in release mode.

Thanks for your help.
CHill60 2-May-16 8:27am    
It's puzzling! Difference between debug and release might be because the memory location affected could be "innocuous" in debug mode - I saw something similar years ago where we actually had to "build in" a buffer in the link file so that a bug in a 3rd party module wouldn't cause a crash. But that doesn't help much - sorry.
David O'Neil 2-May-16 8:41am    
Thanks. It is puzzling!, and has made for far too long of a day already.
Jochen Arndt 2-May-16 8:30am    
You may use the debugger to step through the code to see what happens.

The access violation address of 0x0009A7FC is quite low and is probably not in the address space of your application (compare it with the adresses of the used variables). So the error may be also located somewhere else in your program and occurs delayed at this function.

[EDIT]
I forgot that it does not happen with debug builds.
So you may use poor man's debugging by printing the addresses to a file or a string and show that later.
[/EDIT]

1 solution

Ditch the template. This should work:

C++
#include <string> // or wstring
#include <cctype>


... and ...

C++
for (auto & c: str) c = std::toupper(c);


You probably want to avoid the _toupper macro. One definition looks like this:


C++
#define _toupper(_Char)    ( (_Char)-'a'+'A' )


If you want a copy, rather than in-place, do this:

C++
std::string original;
auto str = original;
for (auto & c: str) c = std::toupper(c);
 
Share this answer
 
v3
Comments
David O'Neil 2-May-16 18:38pm    
Entering the following gives a clue as to what is happening:

wString toUpper(const wString & str) {
wString c;
c=str;
for (auto & c: str) c=std::toupper(c); //ERROR HERE
return c;
}

That gives "... error C3892: 'c': you cannot assign to a variable that is const", so somehow it is turning const.

Rewriting it like the following threw an error about function body redefinition:

wString toUpper(const wString & str) {
wString c(str);
wString::iterator it;
for (it=c.begin(); it!=c.end(); ++it) {
*it = std::toupper(*it);
}
return c;
}

Moving the body into the CPP file instead of the header fixed it.

If you can answer why Visual Studio 2015 is being more aggressive at making things const, I'll mark yours as the solution because it resulted in a method that works.

Thanks much for the pointer, even though I still don't understand why the earlier code didn't simply recompile in 2015 without execution issues, as before.
[no name] 2-May-16 22:13pm    
You've misunderstood my answer. No template - and no function wrapper. Just one line of code for in-place upper case.
My fault for not being more specific. Editing to clarify.

"why Visual Studio 2015 is being more aggressive at making things const"

I'm a bit of a "const nazi" anyways so I haven't noticed 2015 being more const.
David O'Neil 2-May-16 22:26pm    
Thanks for the reply. That makes sense, but may not solve the const problem, because the error was on the lambda function line.
[no name] 3-May-16 6:50am    
Why does you code example above finish with "return c"? Ah, I see.

You use "c" as the auto name but also have a "c" declared as wString. The auto "c" should be a char (or wchar_t) reference - and it should NOT be relative to your "str" which is const. That's from where the const comes. It should be relative to the copy - which is not const.

Rewrite your function like this:

wString toUpper(const wString & str) {
wString copy=str;
for (auto & c: copy) c=std::toupper(c); // notice "str" is not referenced in this line.
return copy;
}
David O'Neil 3-May-16 15:02pm    
Doh! Thanks for catching that. It is working. Don't know why the original stopped in VS2015, but have other things to do that are more important than spending more time on it.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900