Qt Program crashes with another compiler - c++

Could anyone tell me what's wrong with this part of my code? It crashes during execution.
void MainWindow::on_pushButton_clicked()
{
char * cstr = new char [ui->lineEdit->text().length()];
string costam;
costam=ui->lineEdit->text().toStdString();
strcpy(cstr, costam.c_str()); <<<----TROUBLE LINE
int z;
z=costam.length();
for(int n=0;n<z;n++){
string wynik;
wynik=konwersja(cstr[n]);
mors(wynik);
Sleep(300);
}
delete[] cstr;
}
When I try to compile it with MinGW in Qt 5.0.1 everything is OK but with MSVC2010 in Qt 4.8.1 there is a warning:
warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

Your question is wrong. This code compiles and there's nothing about QT here.
strcpy is deprecated because it's unsafe. Alternative is strcpy_s:
strcpy_s( cstr, ui->lineEdit->text().length() + 1, costam.c_str() );
Note that you should allocate ui->lineEdit->text().length() + 1, not ui->lineEdit->text().length(). That's the reason of crash, I guess.
BTW I see no reason to use cstr array in your code at all. As example:
void MainWindow::on_pushButton_clicked() {
string costam;
costam = ui->lineEdit->text().toStdString();
for( size_t n = 0; n < costam.length(); n++ ) {
string wynik;
wynik = konwersja( costam[ n ] );
mors( wynik );
Sleep( 300 );
}
}

Because people are not very aware of security when programming C++, and Windows gets a bad rap because of it, Visual Studio "deprecated" several functions which are common causes of buffer overflows. In this case you should be fine, and can probably just disable the warning by defining _CRT_SECURE_NO_WARNINGS. You may also find this issue with posix functions, too, in which case you would be able to disable those warnings with a separate #define.

Can you change this line strcpy(cstr, costam.c_str()); with strcpy_s(cstr, costam.c_str()); try compiling again?
Also it shouldn't prevent compiling, MSVC2010 is just warning about an unsafe usage. You can also lower the warning level of MSVC2010.

You have two problems here.
The crash is because strcpy will write length + 1 characters into the destination buffer, but your buffer is only of size length. The +1 is for the null termination character, which is not included in length.
The warning is because Microsoft believes its too easy to make mistakes using strcpy and discourages its use. As Joel mentioned, you could enable a define to prevent that warning. I would not recommend semihyagcioglu and Microsoft's suggestion of using strcpy_s, as it's not a portable solution.
I'd also like to note that while fixing those things will make your code compile and run without error, there are other questions. Like: why do you need the cstr variable in the first place? cstr[n] can probably be replaced with costam.data()[n]. Then the cstr variable won't need to exist at all. You won't need the new, delete or strcpy.

Related

VS 2019 stricmp and _stricmp both cause compiler error

The source code itself isn't really in question. It's the compiler's reaction to it. Here's the troublesome snippet:
int XtnUtil::IsExtension(const char * filename, const char * xtn)
{
char* fx = FindExtension(filename); // Get a pointer to the filename extension
if (!fx) return 0; // Bail out if it's not there
if (xtn[0] == '.') xtn++; // Make sure we're looking at the alpha part
return (stricmp(fx, xtn) ? 0 : 1); // TRUE if they're equal
}
I've also used _stricmp instead of stricmp. In either case, the compiler gives me a particularly uninformative message:
It seems to say "Don't use _stricmp, use _stricmp instead." I tried it with and without the underscore and also tried the POSIX equivalent, strcasecmp() but Visual Studio doesn't seem to know that function at all.
For the moment, I've moved past this by simply writing my own function named mystricmp() which is kind of distasteful but seems to work. Right now I'm mostly interested in why the compiler gave me such a funky message, and what would I be able to do about it if the function I had to hand-write weren't trivial?

C++ code with GCC optimisation causes core with invalid free() on strings

I have C++ code that is built with gcc (4.1.2) with -O2.
When this code is compiled and run with no optimisation, the program executes without any issue.
When compiled with O1/O2/O3, the code will crash with a valgrind indicating an invalid free.
This has been narrowed to the string variables inside the function.
The code will read in a file, and will iterate the contents.
I have removed all processing code, and the following code snippet causes the core...
int MyParser::iParseConfig(Config &inConfig)
{
bool keepGoing = true;
while(keepGoing)
{
string valueKey = "";
keepGoing = false;
}
return 0;
}
When this is run with non-optimised, it works fine.
When I build and run this optimised, it will not work.
It looks to be an issue with the way GCC optimises the string class.
Any ideas how we can circumvent this?
If you are overflowing the charIndex, (when i gets higher than 99) who knows what your program state is in... the storage you declare is not very big (2 chars and a null).
I cannot explain why exactly this code crashes for you when compiled with optimizations, perhaps i gets more than 2 digits and you have a buffer overflow, maybe it's something different, but anyway I would change the code:
sprintf(charIndex, "%d", i++);
string valueKey = "";
valueKey.append("Value").append(charIndex);
string value = inConfig.sFindField(valueKey);
like this:
stringstream ss;
ss << "Value" << i++;
string value(ss.str());
It is more C++-like and should work. Try it.
If you are curious if this is really a buffer overflow situation, insert the line:
assert(i < 99);
before the call to printf. Or use snprintf:
snprintf(charIndex, sizeof(charIndex), "%d", i++);
Or make your buffer bigger.
This was an issue with header files being incorrectly included - there was a duplicate include of the MyParser.h file in the list of includes.
This caused some strange scenario around the string optimisation within the GCC optimisation levels.

Optimization makes function return immediately instead of executing

I'm working on VS 2010 express and trying to do some file reading and parsing work
my function goes something like this... (I dropped the boring parts)
void SomeClass::SomeFunc(char *ALName, std::map<...> *chromList, std::map<...> *chromLine)
{
ifstream file;
char tmpBuff[500];
char tmpBuff2[500];
char fileName[350];
char tmp[350];
char *pch;
char *pch2;
.....
file.open(fileName);
while ( file.getline( tmpBuff, 500 ) )
{
....
if ( some_condition == 0 )
{
pch2 = strtok( NULL, "," );
pch = strtok( NULL, "," );
(*chromList)[pch2] = do_some_work( atoi(pch), tmpBuff2 );
strcpy( tmp, get_chrom_line( tmpBuff2 ) );
(*chromLine)[pch2] = tmp;
}
}
file.close();
}
When I change to Release with Optimization set to Maximum speed this function is skipped.
The debugger enters the function and immediately returns.
When i run with Debug setting or Release with the Optimization flag set to disabled, the function runs just fine.
What can be the possible reason for that?
Can I put a preprocessor definition to force "No optimization" on this function while the rest of the code get optimized
Thanks!!
Idan
You should never try to debug optimized code. The line numbers it shows you will rarely match up with what is actually being executed, and forget about reading local variables. That is why there is a "Debug" and "Release" mode.
However, if you really want to, try this to make Visual Studio not optimize that function. You could also put that function in a separate source file and compile it in debug mode.
Are you sure that the function is actually being skipped and that the debugger isn't simply making it look skipped?
If it really isn't being executed then it's almost certain you have undefined behavior that happens to work how you want it when not optimized and the compiler (probably rightfully) optimizes it into non-working code in optimized mode.
That said I see some questionable items: You call strtok with NULL (aside - prefer 0 or nullptr in C++/C++11) without calling it with a valid pointer. Are you aware that strtok is destructive?
Then you use a character pointer to index an array, or presumably (hopefully?) call an overloaded operator[] function with a char* argument.
Since this is C++, your code will be cleaner, safer, and probably easier to debug if you remove all the C-style parsing and do it with string and find/find_first_of/etc depending on your needs.

Program crash in release build

in debug it works fine but when I run the C++ 2010 program in release build (not started from the debugger of visual studio) it crashes. If I comment the lines after the second char*-wchar* conversion it works. Why?
void myfunction(const char *dataBuffer)
{
size_t buffer_size;
mbstowcs_s(&buffer_size, NULL, 0, dataBuffer, _TRUNCATE);
wchar_t *buffer = new wchar_t[buffer_size + 1];
mbstowcs_s(&buffer_size, buffer, buffer_size, dataBuffer, _TRUNCATE);
std::wstring archive_data(buffer);
std::wstringstream archive_stream(archive_data);
boost::archive::text_wiarchive archive(archive_stream);
...
delete [] buffer;
buffer = NULL;
}
Probably because of an uninitialized variable (in debug mode most variables are Initialized to zero but are uninitialized in release)
Most bugs like this can be fixed by fixing all the warnings generated by the compiler (warnings are really logical errors rather than syntax errors). So set you warning level higher re-compile make sure you get zero wanings.
In dev studio set the warning level to four, also set the flag to treat warnings as errors.
Ps. Rather than dynamically allocating a buffer with
wchar_t* buffer = new char_t [<size>];
Use a standard vector (it's exception safe)
std::vector<wchar_t> buffer(<size>);
You can get a pointer to the buffer with:
&buffer[0]
Also: Jen (who deleted his answer) has a good point )I'll delete this and up-vote Jen if he un-deletes his answer.
But you may want to check that the string is correctly NULL terminated L'\0'.
Sometimes compiler attempts to optimize the values which may not allowed to change in the middle of the program.
To notify the compiler to avoid optimization for the particular variable declare as
volatile variable.

sprintf_s crashes

I am getting a crash while executing the following code ocassionally at sprintf_s. This code was working many years without any problems. When I gave the size in strcat_s and sprintf_s as in the statements below, the crash is not appearing. What could be the reason for this?
strcat_s(sztmpCurrDate,100,sztmpCurrTime);
sprintf_s(sztmpCurrDate,100,"%s:%0.3d",sztmpCurrDate,curTime.wMilliseconds););
char sztmpCurrDate[100] = "";
char sztmpCurrTime[100] = "";
SYSTEMTIME curTime;
GetLocalTime(&curTime);
GetLocalTime(&curTime);
GetDateFormat(LOCALE_USER_DEFAULT,
DATE_SHORTDATE,
&curTime,
NULL,
sztmpCurrDate,
100);
GetTimeFormat(LOCALE_USER_DEFAULT,
TIME_FORCE24HOURFORMAT,
&curTime,
"HH':'mm':'ss",
sztmpCurrTime,
100);
strcat_s(sztmpCurrDate," ");
strcat_s(sztmpCurrDate,sztmpCurrTime);
sprintf_s(sztmpCurrDate,"%s:%0.3d",sztmpCurrDate,curTime.wMilliseconds);
From the documentation for sprintf_s:
If copying occurs between strings that overlap, the behavior is undefined.
Your code:
sprintf_s(sztmpCurrDate,"%s:%0.3d",sztmpCurrDate,curTime.wMilliseconds);
copies from the source to the destination sztmpCurrDate. Also, you haven't specified the size of the destination string, which is required by sprintf_s (I don't know how your code even compiled like that). Try:
sprintf_s(sztmpCurrDate + strlen(sztmpCurrDate), 100-strlen(sztmpCurrDate),
":%0.3d",curTime.wMilliseconds);
A better approach, since you're using C++, is to use std::string and then you won't have to worry about this sort of C string manipulation error.
Wrong syntax!!!
Second argument of sprintf_s is length of your buffer and in your case when program crashes you provided pointer to C string (char *). This is absolutely syntax error.
The compiler probably issued a warning, but sadly has let this pass. This is because sprintf_s takes three arguments + variable number of arguments. In your wrong case you provided three arguments so the compiler was satisfied, but he treated your "format string" as "number of arguments" and sztmpCurrDate as "format string".
If you used any other function with fixed number of arguments and you provided less than needed this would be a compile error.
You are probably using the incorrect version:
sprintf_s(sztmpCurrDate,"%s:%0.3d",sztmpCurrDate,curTime.wMilliseconds);
Instead it should be:
int slen = strlen(sztmpCurrDate) + 1;
sprintf_s(sztmpCurrDate, slen, "%s:%0.3d",sztmpCurrDate,curTime.wMilliseconds);
Refer to this sprintf_s for more information.
The code worked correctly, the code is not correct.
sprintf(sztmpCurrDate,"%s:%0.3d",sztmpCurrDate,curTime.wMilliseconds);
Rewrite as
sprintf(&sztmpCurrDate[strlen(sztmpCurrDate)],"%0.3d",curTime.wMilliseconds);
And for home work tell us why .....