glutBitmapString access violation - c++

(OS: Windows 7, Compiler: Visual Studio 2010 C++ compiler)
I've got a correctly working OpenGL program that draws some spheres and models, applies some shaders etc.. etc..
Now I thought it would be nice to add some text, so I added the following three lines to my draw method:
glColor3f(0.5f, 0.5f, 0.5f);
glRasterPos2f(0, 0);
glutBitmapString(GLUT_BITMAP_HELVETICA_12, (unsigned char*)"some text");
Now somehow this all makes my program get stuck in an infinite "access violation" loop, which I can't seem to fix. I even commented all the other draw code out, to just output the text, and it still gives the access violation error, I'm at a loss here because there is nothing that seems to affect this. So does anybody have some pointers ;)) on how to fix this issue?
I could post all my draw code, but I even tried an empty project, so I'm pretty sure it's not the rest of the code.
Edit: I tried narrowing down the error even more, and it seems that glRasterPos2f is throwing the acces violation (weirdly enough). It's not between any glBegin and glEnd calls, and there is no OpenGL error.
Edit2: After some advice I tried the following code, I got rid of the access violation, but still no text is displayed
glColor3f(0.5f, 0.5f, 0.5f);
glRasterPos2f(0.0f, 0.0f);
std::string str("Hello World");
char* p = new char[strlen(str.c_str() + 1)];
strcpy(p, str.c_str());
glutBitmapString(GLUT_BITMAP_HELVETICA_12, (const unsigned char*)p);

glutBitmapString is of type const unsigned char* and not of unsigned char*. Would that help? I had problems with string casting as well.
And I found out, that I wasn't closing my string, because the unsigned char* should be 1 longer than a string. Here was a snippet that solved it for another method with the same parameter type:
string fullPath = TextureManager::s_sTEXTUREFOLDER + filename;
char *filePath = new char[strlen(fullPath.c_str())+1];
strcpy(filePath,fullPath.c_str());
And then you have your char*.

I recently got the same error while attempting to use glBitmapString(). I was using vs2008. I set a breakpoint at the function call and stepped into it (using freeglut_font.c). Inside I noticed that the exception was being thrown upon what was described to be glut not being initialized. So inside my initialization function I added...
char* argv[] = {"some","stuff"}; int argc=2;
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(800,600);
Where of course you can use whatever argc/argv you please. This, as well as what was suggested by Marnix solved the exception errors for me.
Note that I don't actually create a window with glut.

Try putting the string in a temporary variable. The fact that you have to cast should raise a red flag.
glColor3f(0.5f, 0.5f, 0.5f);
glRasterPos2f(0, 0);
unsigned char* s = "some text";
glutBitmapString(GLUT_BITMAP_HELVETICA_12, s);
if const doesn't work, then glutBitmapString() may be modifying the string.

Related

Arduino very randomly freezes on printing float to string via String and sprintf

TLDR: I am getting consistent freezes when printing floats to a String via arduinos String class. Previously I was getting the same freeze with sprintf and %f. I've solved the problem using the PString class, but I would like to understand the issue.
FULL STORY: I have a rather large c++ codebase for arduino SAMD architecture (a MKRZero), that started freezing recently on a line of code I hadn't touched in a long time. This was a call to sprintf with %f, which was oddly working as expected previously. After some research on SO and google, I realized that float formatting via sprintf isn't supported on Arduino, and after ruling out dtostr (due to not being on AVR), I tried with Arduinos String class. This temporarily solved the problem, but the freeze resurfaced after testing the system with some different external periphicals (I2C slaves that can be connected and disconnected). So the exact same code, but some differences in the parts of it being exersized due to the different periphical.
The codebase is quite large (several 1000s lines), and I haven't been able to reproduce with a simple example. So unfortunately without much context, these are the lines that fail:
for (int fieldIndex = 0; fieldIndex < totalFullDataPoints; fieldIndex++) {
char buffer[14];
Serial.println("foo");
// String floatString = String((float)data[fieldIndex], 2); // causes system to freeze
// String floatString = String((float)1024.46, 2); // causes system to freeze
String floatString = String((float)1024.46); // causes system to freeze
// String floatString = String("1024.46"); // works
Serial.println("bar"); // freezes before this
}
The bug is extremely unstable in that I can cause it to not trigger by modifying unrelated stuff other places in the code or disconnecting a sensor (I2C slave) from my arduino. But when it's present it's consistent in that it happens every run. I even had a version of my code that worked - but removing there three lines would cause it to freeze again:
String floatString = "14123.123";
Serial.println("Float String: ");
Serial.println(floatString);
I'm quite certain it's not a memory problem, and as far as I can tell it's not a case of pointers or non-terminated strings exploding.
I ended up using PStrings (https://github.com/boseji/PString-Arduino-lib) due to this post https://forum.arduino.cc/t/use-pstring-to-avoid-crashes-due-to-string-sprintf-or-dtostrf-float-issues/230946 but I'm frustrated and curious as to why it freezes in such a seemingly random fashion when creating floats via String is supposed to be supported.
After a lot of debugging, it seems that the issue indeed does have to do with ability of Arduino to print floats to string, and not with pointers or non-terminated string issues in my code.
It seems to be stalling in the dtostrf() call of the String constructor:
// ~/.platformio/packages/framework-arduino-samd/cores/arduino/api/String.cpp
String::String(float value, unsigned char decimalPlaces)
{
static size_t const FLOAT_BUF_SIZE = FLT_MAX_10_EXP + FLT_MAX_DECIMAL_PLACES + 1 /* '-' */ + 1 /* '.' */ + 1 /* '\0' */;
init();
char buf[FLOAT_BUF_SIZE];
decimalPlaces = min(decimalPlaces, FLT_MAX_DECIMAL_PLACES);
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); // <-- HERE
}
and it seems to be related to the assembler call to _print_float within the dtostrf() function:
// ~/.platformio/packages/framework-arduino-samd/cores/arduino/api/deprecated-avr-comp/avr/dtostrf.c.impl
char *dtostrf (double val, signed char width, unsigned char prec, char *sout) {
asm(".global _printf_float"); // If this line is uncommented, the stall wont happen
char fmt[20];
sprintf(fmt, "%%%d.%df", width, prec);
sprintf(sout, fmt, val); // If the above line is not commented out, the system will freeze here
return sout;
}
I realize this might be a pretty unsatisfactory answer for anyone coming across this thread... But for what it's worth, the solution for us will be to use PString (https://github.com/boseji/PString-Arduino-lib) as they at least seem stable so far.
I will follow up on this thread if the issue ever surfaces again despite using PStrings

LPCWSTR to char* and vice versa

I'm working on a simple project with DirectX9. I'm having a little snag with some conversion of data types, and I've done some research, but haven't found anything particularly useful. Let's start with the code:
LPDIRECT3DSURFACE9 LoadSurface(char *fileName, D3DCOLOR transColor)
{
LPDIRECT3DSURFACE9 image = NULL;
D3DXIMAGE_INFO info;
HRESULT result;
result = D3DXGetImageInfoFromFile(fileName, &info);
if (result != D3D_OK) return NULL;
result = d3ddev->CreateOffscreenPlainSurface(
info.Width, //width of the surface
info.Height, //height of the surface
D3DFMT_X8R8G8B8, //surface format
D3DPOOL_DEFAULT, //memory pool use
&image, //reference to image
NULL); //reserved - ALWAYS NULL
//make sure file loaded properly
if (result != D3D_OK) return NULL;
return image;
}
At line 6, I'm getting the error for the variable fileName:
IntelliSense: argument of type "char *" is incompatible with parameter of type "LPCWSTR"
I also get the exact same error message at the second and third parameters when trying to use MessageBox's:
if (d3ddev == NULL)
{
MessageBox(hWnd, "Error Creating Direct3D Device", "Error", MB_ICONERROR);
return 0;
}
I've used code exactly like this before and had no problems. No idea what is going on - especially because LPCWSTR and char* are essentially the same thing...
Any help is appreciated!! Thank you
The most probable reason that you had no problem before is that you turned on unicode in Visual C++ project's settings. See the accepted answer here to turn it off again (if it's possible for you):
How do I turn off Unicode in a VC++ project?
Otherwise you need to convert char * to wchar_t * using MultiByteToWideChar function.
I've used code exactly like this before and had no problems.
No, you haven't.
LPCWSTR and char* are essentially the same thing...
No, they're not.
If you read the documentation, you'll see that a LPCWSTR is a const wchar_t*.
You should take a const wchar_t* into your function instead.
If you really want to convert to a char*, and don't mind that (at least in one of the two directions) this makes no sense, then you can read the answers to the following questions:
Convert char[] to LPCWSTR
How to convert char* to LPCWSTR?
… and apply const_cast afterwards. But, seriously, please don't.
Figured it out through looking through the DirectX header files... If anyone is having this same problem, rather than using the:
D3DXGetImageInfoFromFile(varName, &info);
Instead, use:
D3DXGetImageInfoFromFileA(varName, &info);
Same goes for MessageBox's... Use
MessageBoxA(handleVar, messageVar, titleVar, iconType);
*This comes with the caveat that your project property settings for character sets are set to Unicode. It becomes unnecessary if you switch that to Multi-byte.
As always, Thanks to those that actually contributed and helped me with this; and No Thanks to those who simply post on boards to ridicule or demean those who are less experienced - great use of your time.

Qt Program crashes with another compiler

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.

GLSL Compiling error when more than one char pointer (glShaderSource)

What's wrong with this code for a 3.30 OpenGL and GLSL version?
const char *vertSrcs[2] = { "#define A_MACRO\n", vShaderSrc };
const char *fragSrcs[2] = { "#define A_MACRO\n", fShaderSrc };
glShaderSource(vId, 2, vertSrcs, NULL);
glShaderSource(fId, 2, fragSrcs, NULL);
I gather the shader state with GL_COMPILE_STATUS after the its compiled, get this error:
Vertex shader failed to compile with the following errors:
The purpose for this macro is to change type qualifier on a color I passed from the vertex to the fragment, maybe there is another way to do that using a uniform and the layout but the question is why would the shader fail? I wonder if there is another OpenGL command which must specify the 2 char pointers.
By the way, this works:
...
glShaderSource(vId, 1, &vertSrcs[1], NULL);
...
EDIT: since I can't answer my own questions, found the solution
Very strange problem, the string loader happens to be the problem. Without using ifstream along with std::ios::in | std::ios::binary flags, the string was loaded with some garbage information to the end even with null terminated, therefore concatenating the strings will produce the error.
For some reason the gl compiler didn't complain before with the single string version, besides calling
inStream.flags(std::ios::in | std::ios::binary)
wasn't enough, it need to be specified when opening, didn't find any doc for this.
The very first nonempty line of a GLSL shader must be a #version preprocessor statement. Anything else is an error.

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.