C++ - Having problems defining a variable inside main() function - c++

I am trying to define a variable from an external library in C++, Visual Studio 2010. It only works when I put it outside of the main function.
This code crashes:
#include "StdAfx.h"
#include <ogdf\basic\Graph.h>
#include <ogdf\basic\graph_generators.h>
int main()
{
ogdf::Graph g;
ogdf::randomSimpleGraph(g, 10, 20);
return 0;
}
It gives me an unhandheld exception: Access violation.
However, if it is outside main function, it works without any problem:
#include "StdAfx.h"
#include <ogdf\basic\Graph.h>
#include <ogdf\basic\graph_generators.h>
ogdf::Graph g;
int main()
{
ogdf::randomSimpleGraph(g, 10, 20);
return 0;
}
Do you have any how do I fix that? I assume, that it is caused by some kind of linking problem.
EDIT: It looks like the problem is not the initialization of the variable. It throws an exception, when the application exits.
int main()
{
ogdf::Graph g; // No problem
ogdf::randomSimpleGraph(g, 10, 20); // No problem
int i; // No problem
std::cin>>i; // No problem
return 0; // Throws an exception after read i;
}
Call stack:
The output is:
First-chance exception at 0x0126788f in graphs.exe: 0xC0000005: Access violation writing location 0x00000000.
Unhandled exception at 0x0126788f in graphs.exe: 0xC0000005: Access violation writing location 0x00000000.

Works on my machineā„¢.
Esoteric errors like that are often a result of binary incompability. Basically, because of different compiler/preprocessor options, effective headers that your code and the library "see" are different.
For instance, if you have a library with following header code:
class Foo
{
#ifdef FOO_DEBUG
int debug_variable;
#endif
int variable;
};
Library function:
void bar(Foo& foo)
{
std::cout << foo.variable;
}
And client code:
Foo foo;
foo.variable = 666;
bar(foo);
If FOO_DEBUG is not in sync amongst client and the library, this will possibly crash and burn -- variable will have different expected offset.
In your case, I suspect one of the following may be true:
You have built the ogdf with different compiler than your code
If not, you ogdf and your code have different build configurations (Release vs Debug)
Both are debug, but you have defined OGDF_DEBUG (as recommended here)
You have different "Struct Member Alignment" setting

Related

C++ bit7z : Exception thrown at ... in ... Microsoft C++ exception: bit7z::BitException at memory location 0x001AF440 & paths of directory and files

I'm trying to create a program that, on execution, zips a given directory. Most of my errors have been resolved and I am hopefully getting to the end of this, but I still have the issue of an exception being thrown and a question regarding the program. I code in C++20 and on Visual Studio 2019.
I've come across this exact error when debugging the program:
Exception thrown at 0x76820B42 in aixLogger.exe: Microsoft C++ exception: bit7z::BitException at memory location 0x001AF440.
I already checked with a breakpoint what code is giving me this error:
catch (const BitException& ex) {
ex.what(); //<-
}
The code runs otherwise and isn't giving me any error messages, the breakpoint activates on the line I marked with an arrow (not actually part of my code).
To eliminate further possible edits I will add the rest of my code as well:
main.cpp
#include <QCoreApplication>
#include <string>
#include <iostream>
#include <filesystem>
#include <bit7z.hpp>
#include "main.h"
#include <bitcompressor.hpp>
namespace fs = std::filesystem;
using namespace bit7z;
using namespace std;
int main(int argc, char* argv[])
{
QCoreApplication a(argc, argv);
try {
Bit7zLibrary lib{ L"7z.dll" };
BitCompressor compressor{ lib, BitFormat::Zip };
//vector< wstring > files = { L"aretz/Downloads/test" };
wstring dir = { L"D: / local / aretz / Programmierung / git - workplace / aixLogger / test /" } ;
wstring zip = { L"zippedtest.zip" };
compressor.compressDirectory(dir, zip);
}
catch (const BitException& ex) {
ex.what();
}
return a.exec();
}
void AIXLogger::CompressDir() {
/*try {
Bit7zLibrary lib{ L"7z.dll" };
BitCompressor compressor{ lib, BitFormat::Zip };
vector< wstring > files = { L"C:/Users/aretz/Downloads/test" };
wstring zip = { L"zippedtest.zip" };
compressor.compressFiles(files, zip);
}
catch (const BitException& ex) {
ex;
}*/
}
main.h
#pragma once
#include <qwidget.h>
#include <qobject.h>
#include <bit7z.hpp>
class AIXLogger : public QWidget
{
Q_OBJECT
public slots:
public:
void CompressDir();
};
I've currently commented out the function CompressDir() as I can't call it in my main since it gives me either a syntax error or tells me the identifier is undefined.
Syntax Error:
AIXLogger.CompressDir(); the dot is marked as the error
identifier is undefined:
CompressDir();
I don't know what exactly is causing the catch to thrown an exception. From other posts I suspected that my paths for the files and directories are at fault, but changing them or moving my test directory didn't help at all. Removing the try and catch lines from my codeblock only adds the same error message where Exception Thrown is being replaced by Unhandled Exception. Thanks to anyone who can help.
I already checked with a breakpoint what code is giving me this error:
catch (const BitException& ex) {
ex.what(); //<-
}
The code runs otherwise and isn't giving me any error messages
The code isn't giving you any error message since you're not doing anything with the information provided by the thrown exception.
You're simply calling ex.what() without, for example, printing the error message string it returns, e.g., via std::cout.
the breakpoint activates on the line I marked with an arrow (not actually
part of my code).
I don't know what exactly is causing the catch to thrown an exception. From other posts I suspected that my paths for the files and directories are at fault, but changing them or moving my test directory didn't help at all.
The ex.what() error message should give you more details about the actual issue you're having.
By the way, I'm the author of the bit7z library, and from my experience and looking at the code you posted, I can think of some possible causes (the most common ones):
The program could not find the 7z.dll library.
Please ensure that the DLL is in the same directory as the executable or in one of the default DLL search paths of Windows.
The program could not find the directory path to be compressed.
As before, make sure that the path exists.

Strange behaviour when using C++17 static inline members in Visual Studio

Yesterday I asked a question about this problem, but I wasn't able to give a MVCE. I've managed to reproduce this with a simple program. The problem is with using an std::list as a static inline declaration in a class. Microsoft Visual Studio does support this new C++17 feature. It had some bugs as of March, but as far as I know they've been fixed since. Here are instructions of how I can get this problem, this happens in debug mode.
In main.cpp
#include <iostream>
#include "header1.h"
int main()
{
return 0;
}
In header1.h:
#include <list>
struct Boo
{
static inline std::list<int> mylist;
};
In anotherCPP.cpp
#include "Header1.h"
When the program exits main() it destroys all the static objects and throws an exception.
If this doesn't crash, maybe on your system the compiler/linker optimised some code out, so you can try making main.cpp and anotherCPP.cpp do something. In anotherCPP.cpp:
#include <iostream>
#include "Header1.h"
void aFunction()
{
std::cout << Boo::mylist.size();
}
And make main.cpp:
#include <iostream>
#include "Header1.h"
void aFunction();
int main()
{
std::cout << Boo::mylist.size();
afunction();
return 0;
}
When the program exits I get an exception here when the std::list is being cleared. Here is the Visual Studio debug code where it crashes:
for (_Nodeptr _Pnext; _Pnode != this->_Myhead(); _Pnode = _Pnext)
{ // delete an element
_Pnext = _Pnode->_Next; // Here: Exception thrown:
// read access violation.
// _Pnode was 0xFFFFFFFFFFFFFFFF.
this->_Freenode(_Pnode);
}
This happens only if I declare the static inline std::list< int > mylist in the class. If I declare it as static std::list< int > mylist in my class and then define it separately in one .cpp as std::list< int > Boo::mylist; it works fine. This problem arises when I declare the std::list static inline and I include the header for the class in two .cpp files.
In my project I have stepped through the std::list clear loop from above, I took note of the "this" pointer address. I stepped through the loop as it freed nodes in my list. It then came back to free other std::lists, including in std::unordered_map (as they also use std::lists from the looks of it). Finally when the read access exception is thrown and _Pnode is an invalid pointer address, I noticed the "this" pointer address is the same as the "this" pointer address when clearing std::list< int > mylist, which makes me think that it's trying to delete it twice, and probably why it's crashing.
I hope someone can reproduce this, I'm not sure what this is, if it's a bug or something I'm doing wrong. Also this happens for me in 32 and 64 bit, but only in debug mode, because the node freeing loop I provided is under a macro:
#if _ITERATOR_DEBUG_LEVEL == 2
This issue was filed as a bug here under the title "Multiple initializations of inline static data member in Debug mode".
This was found in Visual Studio 2017 version 15.7.
The VS compiler team has accepted this and have fixed the problem in an upcoming release.

C++ std::mutex lock() access violation in Visual Studio 2017

When I'm trying to run executable compiled using VS2017 I catch
Exception thrown at 0x00007FFF05BC1063 (msvcp140d.dll) in a.exe: 0xC0000005: Access violation reading location 0x0000000000000000. immediately after launching.
After debugging i figured out that it happens when I'm trying to lock static mutex _coutMutex. How can I fix it because when I have compiled using mingw it worked fine. Here is part of my code:
Game.hpp:
#include "Logger.hpp"
class Game
{
public:
static Logger logger;
};
Game.cpp:
#include "Game.hpp"
Logger Game::logger{ "logs/client", Logger::LoggingLevels::Info,
Logger::LoggingLevels::Trace, 2, 100 };
Logger.hpp:
#include <mutex>
class Logger
{
public:
Logger(std::string path, short consoleLoggingLevel, short
fileLoggingLevel, uint32_t count, size_t maxSize);
enum LoggingLevels : short
{
Off = 0,
Fatal = 1,
Error = 2,
Warn = 3,
Info = 4,
Debug = 5,
Trace = 6
};
void _addToQueue(std::string data);
private:
static std::mutex _coutMutex;
};
Logger.cpp:
std::mutex Logger::_coutMutex;
Logger::Logger(std::string path, short consoleLoggingLevel,
short fileLoggingLevel, uint32_t count, size_t maxSize)
{
_addToQueue("dd/mm/yyyy hh:mm:ss.sss\n");
}
void Logger::_addToQueue(std::string data)
{
_coutMutex.lock();
std::cout << data;
_coutMutex.unlock();
}
main.cpp:
#include "Logger.hpp"
#include "Game.hpp"
int main()
{
Game game;
}
As Richard Critten suggests, this must be the global initialisation order problem.
You have 2 global variables, logger and _coutMutex, and these are in a different compilation unit. The order which they are initialized is not defined.
When Logger's constructor runs, _coutMutex is not initialized yet, but _addToQueue wants to use it.
You could have three solutions:
Avoid using global objects. Or avoid using global constructors which do something serious (if you remove _addToQueue from logger constructor, it will work).
put these global variables into one compilation unit, in correct order
add an accessor function for _coutMutex, and define mutex inside of it (as a static variable). Beware of this solution, as it has its drawbacks (speed, thread safety)

Exception in C++ with function pointers: Access violation executing location 0x00000000

I'm having some trouble with function pointers and passing them as inputs to other functions in C++. I've written some simplified code that sums up the trouble that I'm having. I have two .cpp files as below
functions.cpp
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#define _CRT_SECURE_NO_WARNINGS
typedef double(*real_function)(double);
double one(double x) {
return double(1);
}
void applyfunction(int length, real_function f, double* result) {
int j;
result[0] = 0;
for (j = 1; j < length; j++) {
result[j] = f(result[j - 1]);
}
}
Source.cpp
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#define _CRT_SECURE_NO_WARNINGS
typedef double(*real_function)(double);
real_function one;
void applyfunction(int, real_function, double*);
int main(void) {
double* result;
result = (double*)calloc(10, sizeof(double));
applyfunction(10, one, result);
return(0);
}
When I compile this, I get the following error in Visual Studio 2015
Exception thrown at 0x00000000 in Project3.exe: 0xC0000005: Access violation executing location 0x00000000.
If there is a handler for this exception, the program may be safely continued.
What is going wrong? The funny thing is that if we define those functions one and applyfunction in the source.cpp file (i.e. put all code in a single file), things seem to work. So, I think that it must be something very simple that I am getting wrong. Thank you for any help.
real_function one;
This creates a global variable one which is initialized to a null pointer.
applyfunction(10, one, result);
You then pass that null pointer to applyfunction...
result[j] = f(result[j - 1]);
...wherein you try to call it, generating the null pointer exception.
To fix this, don't create a variable one in Source.cpp. Instead, add a prototype that matches the definition in functions.cpp. In other words, replace real_function one; with
double one(double x);
real_function one;
doesn't declare the function one in the other file; it defines a function pointer called one. Because it's global (and thus has static storage), it's initialized to null. Your program crashes because it's trying to call a null pointer.
One way to fix this is to change
typedef double(*real_function)(double);
to
typedef double real_function(double);
This way real_function actually names a function type (not a pointer).

Catching exception from a specialized method

Let's consider the following three files.
tclass.h:
#include <iostream>
#include <vector>
template<typename rt>
class tclass
{
public:
void wrapper()
{
//Storage is empty
for(auto it:storage)
{
}
try
{
thrower();
}
catch(...)
{
std::cout << "Catch in wrapper\n";
}
}
private:
void thrower(){}
std::vector<int> storage;
};
spec.cpp:
#include "tclass.h"
//The exact type does not matter here, we just need to call the specialized method.
template<>
void tclass<long double>::thrower()
{
//Again, the exception may have any type.
throw (double)2;
}
main.cpp:
#include "tclass.h"
#include <iostream>
int main()
{
tclass<long double> foo;
try
{
foo.wrapper();
}
catch(...)
{
std::cerr << "Catch in main\n";
return 4;
}
return 0;
}
I use Linux x64, gcc 4.7.2, the files are compiled with this command:
g++ --std=c++11 *.cpp
First test: if we run the program above, it says:
terminate called after throwing an instance of 'double'
Aborted
Second test: if we comment for(auto it:storage) in the tclass.h file, the program will catch the exception in main function. WATWhy? Is it a stack corruption caused by an attempt to iterate over the empty vector?
Third test: lets uncomment back the for(auto it:storage) line and move the method specialization from spec.cpp to main.cpp. Then the exception is caught in wrapper. How is it possible and why does possible memory corruption not affect this case?
I also tried to compile it with different optimization levels and with -g, but results were the same.
Then I tried it on Windows 7 x64, VS2012 express, compiling with x64 version of cl.exe with no extra command line arguments. At the first test this program produced no output, so I think it just crashed silently, so the result is similar with Linux version. For the second test it produced no output again, so result is different from Linux. For the third test the result was similar with Linux result.
Are there any errors in this code so they can lead to such behavior? May the results of the first test be caused by possible bug in compilers?
With your code, I have with gcc 4.7.1:
spec.cpp:6: multiple definition of 'tclass<long double>::thrower()'
You may correct your code by declaring the specialization in your .h as:
template<> void tclass<long double>::thrower();