So I'm fairly new to C++ and I've only started to code into it a few weeks or so. I've been facing a problem that I could not manage to fix. Every time I learned a new programming language, I give myself the challenge to make a little program (not too complex) which groups everything I've learned about that language (functions, classes, arrays, pointers and so on) so I can get a good understand of how actually coding in that language is.
So I decided to make my first C++ program called Chek to check the current MBPS (connection speed) every hour, minutes, or second that the user can input. Like all of my programs, I use a structure that I always use that I discovered while coding in Java (Since I know Java fluidly). Which looks like this:
I've also added a comment of where my issue is in the whole in Lib/Arguments.cpp.
Let's say I was to code Chek in Java. I would do my structure like:
Chek or Main class
|- Core
|- Core (The class that handles initiating each core's libraries)
|- Arguments (For parsing, checking and understand arguments)
|- Broadcast (To print to screen and so on)
|- Network (For network interaction)
|- Logs (To save to file logs)
Then the rest ...
Each Core's lib is handled by the Core, like... To call the Broadcast methods, I would do:
Main().getCore().getBroadcast().BroadcastMsg("Hello!");
So I can access all libraries, methods, and variables without creating deadlocks or any infinite importing loops.
My problem is I'm trying to do this in C++ but it's not working! I've tried a lot of stuff, changing pointers to Object and so on but it doesn't work so I need help!
Here's my code (I'm also using Visual Studio):
Chek.cpp:
#include "pch.h"
#include "Main.h"
#include "Core.h"
#include <iostream>
int main(int argc, char *argv[])
{
Core* Ptr = new Core;
Main OBJ; Main* Ptr2; Ptr2 = &OBJ;
std::cout << "Generated PTR's!" << std::endl;
std::cout << "Core PTR -> " << Ptr << std::endl;
std::cout << "Main PTR -> " << Ptr2 << std::endl << std::endl;
Ptr2->SetCrPtr(Ptr);
Ptr2->loadChek(argv);
}
Main/Main.h:
#pragma once
#ifndef __MAIN_H
#define __MAIN_H
class Core;
class Main
{
public:
Main();
private:
Core* CrPtr;
public:
void loadChek(char *arguments[]);
void SetCrPtr(Core* Ptr);
Core* getCrPtr();
};
#endif
Main/Main.cpp:
#include "pch.h"
#include "Main.h"
#include "Core.h"
#include "Arguments.h"
#include "Broadcast.h"
#include <iostream>
using namespace std;
Main::Main() : CrPtr() {};
void Main::SetCrPtr(Core* Ptr)
{
std::cout << "[Main] Setting CrPtr to " << Ptr << std::endl;
this->CrPtr = Ptr;
}
Core* Main::getCrPtr()
{
return this->CrPtr;
}
void Main::loadChek(char *arguments[])
{
char *allArguments[sizeof(arguments)];
this->CrPtr->SetMnPtr(this);
this->CrPtr->setArguments();
this->CrPtr->setBroadcast();
this->CrPtr->getBroadcast()->Log(1, "Loading arguments ...\n");
this->CrPtr->getArguments()->parseArguments(arguments, allArguments);
}
Core/Core.h:
#pragma once
#ifndef __CLASS_H
#define __CLASS_H
#include "Arguments.h"
#include "Broadcast.h"
class Main;
class Core
{
public:
Core();
private:
Main* MnPtr;
Arguments* ArgPtr;
Broadcast* BrdPtr;
public:
Arguments* getArguments();
void setArguments();
Broadcast* getBroadcast();
void setBroadcast();
void SetMnPtr(Main* Ptr);
};
#endif
Core/Core.cpp:
#include "pch.h"
#include "Core.h"
#include "Main.h"
Core::Core() : MnPtr() {}
void Core::SetMnPtr(Main* Ptr)
{
std::cout << "[Core] Setting MnPtr to " << Ptr << std::endl;
this->MnPtr = Ptr;
}
void Core::setArguments()
{
this->ArgPtr = new Arguments;
std::cout << "[Core] Setting Argument's MnPtr to " << this->MnPtr << std::endl;
this->ArgPtr->SetMnPtr(this->MnPtr);
}
void Core::setBroadcast()
{
this->BrdPtr = new Broadcast;
std::cout << "[Core] Setting Broadcast's MnPtr to " << this->MnPtr << std::endl;
this->BrdPtr->SetMnPtr(this->MnPtr);
}
Arguments* Core::getArguments()
{
return ArgPtr;
}
Broadcast* Core::getBroadcast()
{
return BrdPtr;
}
Lib/Arguments.h:
#pragma once
class Main;
class Arguments
{
public:
Arguments();
private:
Main* MnPtr;
public:
void parseArguments(char *arguments[], char *argumentsElements[]);
void SetMnPtr(Main* Ptr);
Main* GetMnPtr();
};
Lib/Arguments.cpp:
#include "pch.h"
#include "Arguments.h"
#include <iostream>
Arguments::Arguments() : MnPtr() {}
void Arguments::SetMnPtr(Main* Ptr)
{
std::cout << "[Arguments] Setting MnPtr to " << Ptr << std::endl;
this->MnPtr = Ptr;
}
Main* Arguments::GetMnPtr()
{
return this->MnPtr;
}
void Arguments::parseArguments(char *arguments[], char *argumentsElements[])
{
try {
if (sizeof(arguments) == 1 || sizeof(arguments) > 4) throw 1;
}
catch (int errorCode) {
if (errorCode == 1) std::cout << "Wrong usage!\n\nUsage: chek.exe <timeout-in-miliseconds> <log-file-path>\nExample: chek.exe 10000 saturday_log_file.txt\n";
}
std::cout << "Size -> " << sizeof(arguments) << std::endl;
for(int i=0; i<sizeof(arguments); i++)
{
// The error is produced here, for some reason after MnPtr,
// nothing is recognised. Like getCrPtr()... has never been declared?
this->MnPtr->getCrPtr()->getBroadcast()->(1, "Works!");
}
}
Lib/Broadcast.h:
#pragma once
#include <iostream>
#include "Main.h"
class Broadcast
{
public:
Broadcast();
private:
Main* MnPtr;
public:
void Log(unsigned int statusLevel, std::string message);
void SetMnPtr(Main* Ptr);
};
Lib/Broadcast.cpp:
#include "pch.h"
#include "Broadcast.h"
#include <iostream>
#include <string>
using namespace std;
Broadcast::Broadcast() : MnPtr() {}
void Broadcast::SetMnPtr(Main* Ptr)
{
std::cout << "[Broadcast] Setting MnPtr to " << Ptr << std::endl;
this->MnPtr = Ptr;
}
void Broadcast::Log(unsigned int statusLevel, string message)
{
switch (statusLevel) {
case 1:
cout << "[.] " << message;
break;
case 2:
cout << "[+] " << message;
break;
case 3:
cout << "[!] " << message;
break;
case 4:
cout << "[X] " << message;
break;
}
}
Errors:
I get 3 errors.
Visual Studio Error (When you hover it):
Arguments *const this
Pointers to incomplete class is not allowed.
From the error box (Visual Studio):
Error C2027 use of undefined type 'Main' Chek2 c:\users\xxx\documents\programming\c++\vs workspace\chek2\arguments.cpp 30
Error (active) E0393 pointer to incomplete class type is not allowed Chek2 C:\Users\xxx\Documents\Programming\C++\VS Workspace\Chek2\Arguments.cpp 30
Compiler Errors:
1>c:\users\xxx\documents\programming\c++\vs workspace\chek2\arguments.cpp(30): error C2027: use of undefined type 'Main'
1>c:\users\xxx\documents\programming\c++\vs workspace\chek2\arguments.h(3): note: see declaration of 'Main'
If anyone could help me with this. I would highly appreciate it! I hope it's not too hard of a problem- fairly new to C++ so I don't know exactly what this is compared to Java.
Thanks to #drescherjm for answering in comments. I just needed to add:
#include "Main.h"
#include "Core.h"
Inside Arguments.cpp's includes!
Related
This question already has answers here:
What advantages does C++20's std::source_location have over the pre-defined macros __FILE__, __LINE__ and __FUNCTION__?
(3 answers)
Closed 3 months ago.
Is it possible to print the caller source file name calling a function defined in another file, without passing __FILE__ explicitly and without using preprocessor tricks?
// Header.h
#include <iostream>
#include <string>
using namespace std;
void Log1(string msg) {
cout << __FILE__ << msg << endl; // this prints "Header.h"
}
void Log2(string file, string msg) {
cout << file << msg << endl;
}
inline void Log3(string msg) {
cout << __FILE__ << msg << endl; // this prints "Header.h"
}
// Source.cpp
#include "Header.h"
int main()
{
Log1(" Test 1");
Log2(__FILE__, " Test 2");
Log3(" Test 3");
}
With this code, this is what I get:
pathTo\Header.h Test 1
pathTo\Source.cpp Test 2
pathTo\Header.h Test 3
I would have expected the last call to print: pathTo\Source.cpp Test 3
You could use std::source_location:
// library.h
#pragma once
#include <source_location>
#include <string>
void Log(std::string msg, const std::source_location loc =
std::source_location::current());
// library.cpp
#include "library.h"
#include <iostream>
void Log(std::string msg, const std::source_location loc) {
std::cout << loc.file_name() << ' '<< msg << '\n';
}
// Source.cpp
#include "library.h"
int main() {
Log("Test 1"); // Prints "Source.cpp Test 1"
}
This requires C++20. Prior to C++20 you can use boost::source_location.
Trying to write a cpp code to print out messages from camera image using darknet. I built a class in which there is mutex method which I use for utilizing callback message in multiple threads. Although catkin_make builds the file successfully, it gives segmentation error when I run the ros command with rosrun . The code is as follows:
#include "ros/ros.h"
#include "darknet_ros_msgs/BoundingBoxes.h"
#include "darknet_ros_msgs/BoundingBox.h"
#include<string>
#include<thread>
#include<iostream>
#include <mutex>
#include "geometry_msgs/Twist.h"
class Firstolo
{
private:
std::mutex yolo_mtx;
darknet_ros_msgs::BoundingBoxes last_yolo_msg;
public:
void callback(const darknet_ros_msgs::BoundingBoxes& msg)
{
std::lock_guard<std::mutex> lck(yolo_mtx);
last_yolo_msg = msg;
}
const darknet_ros_msgs::BoundingBoxes getYoloLastMsg()
{
std::lock_guard<std::mutex> lck(yolo_mtx);
return last_yolo_msg;
}
void dothejob()
{
std:: cout << "Here it goes: " << getYoloLastMsg().bounding_boxes[0].xmin << std::endl;
std:: cout << "Here it goes: " << getYoloLastMsg().bounding_boxes[0].xmax << std::endl;
std:: cout << "\033[2J\033[1;1H";
}
Firstolo()
{
}
Firstolo(Firstolo&)
{
std::mutex yolo_mtx;
}
~Firstolo()
{
}
};
int main( int argc, char **argv)
{
ros::init(argc,argv,"cood_subscriber");
Firstolo nc;
ros::NodeHandle nh;
ros::Subscriber sub;
sub = nh.subscribe("/darknet_ros/bounding_boxes", 100, &Firstolo::callback, &nc);
nc.dothejob();
ros::spin();
return 0;
}
Edit: It turns out that the problem is in the void dothejob(). I added std::lock_guardstd::mutex lck(yolo_mtx); to the void dothejob() and Segmentation error no longer shows up. Now the only remaining problem is that std:: cout << "Here it goes: " << getYoloLastMsg().bounding_boxes[0].xmin << std::endl; line keeps waiting for messages rather than printing them out. In fact, messages naturally should appear since there is darknet running in the background and generating messages.
I have a working program which must be split into multiple parts, for edition purposes. This program is needed to keep user login info in char arrays to be able to connect to SQL, and this connection info is used many times in parts of the program that will end up in separated .cpp files, which will compile in a single program.
The problem is that if they are declared in just one file, they will be missing in the rest, and if they are declared in all of them, there will be duplicated definitions.
So, to make a concrete and simple example, if I have the following code:
#include <mysql++/mysql++.h>
#include <iostream>
using namespace std;
using namespace mysqlpp;
char server[] = "localhost";
char user[] = "root";
char pass[] = "xxxxxxx";
char db[] = "prog";
void function()
{
Connection con;
con.connect("", server, user, pass);
con.select_db(db);
//action1...;
}
void separated_function()
{
Connection con;
con.connect("", server, user, pass);
con.select_db(db);
//action2...;
}
int
main( int argc, char *argv[] )
{
cout << "INICIO\n";
function();
separated_function();
//something else with the mentioned variables...;
cout << "FIN\n";
return 0;
}
How can it be split correctly, to have function(), another_function() and main() in separated .cpp files,and make server, user, pass and db avaliable to all of them.
I know there must be many ways, but any working one is good enough, since I'm not getting any results so far.
NOTE: This question is not about how to use the variables with MySQL, but how to split the program correctly.
You want to use extern in the seperated source files, or in a common header that is included in the seperated source files. You will define them in one (and only one) cpp file. Here is an example:
main.h
void function();
void seperated_function();
namespace myGlobals {
extern char server[];
extern char user[];
extern char pass[];
extern char db[];
}
main.cpp
#include <iostream>
#include "main.h"
namespace myGlobals {
char server[] = "localhost";
char user[] = "root";
char pass[] = "xxxxxxx";
char db[] = "prog";
}
int main(int argc, char *argv[]) {
std::cout << "main.cpp\n";
std::cout << myGlobals::server << "\n";
std::cout << myGlobals::user << "\n";
std::cout << myGlobals::pass << "\n";
std::cout << myGlobals::db << "\n\n";
function();
seperated_function();
return 0;
}
function.cpp
#include <iostream>
#include "main.h"
void function() {
std::cout << "function.cpp\n";
std::cout << myGlobals::server << "\n";
std::cout << myGlobals::user << "\n";
std::cout << myGlobals::pass << "\n";
std::cout << myGlobals::db << "\n\n";
}
seperated_function.cpp
#include <iostream>
#include "main.h"
void seperated_function() {
std::cout << "seperated function.cpp\n";
std::cout << myGlobals::server << "\n";
std::cout << myGlobals::user << "\n";
std::cout << myGlobals::pass << "\n";
std::cout << myGlobals::db << "\n\n";
}
The namespace myGlobals is not required, but if I am going to use global variables I at least like to put them in their own namespace.
I am trying to use clang+llvm 3.6 to JIT compile several C functions (each can eventually be very large).
Unfortunately I the function pointer that LLVM provides makes the program SEGFAULT.
So far I have following code:
#include <iostream>
#include <clang/CodeGen/CodeGenAction.h>
#include <clang/Basic/DiagnosticOptions.h>
#include <clang/Basic/TargetInfo.h>
#include <clang/Basic/SourceManager.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Frontend/CompilerInvocation.h>
#include <clang/Frontend/FrontendDiagnostic.h>
#include <clang/Frontend/TextDiagnosticPrinter.h>
#include <clang/Frontend/Utils.h>
#include <clang/Parse/ParseAST.h>
#include <clang/Lex/Preprocessor.h>
#include <llvm/Analysis/Passes.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#include <llvm/ExecutionEngine/MCJIT.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/IR/Verifier.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/LegacyPassManager.h>
#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/Support/ManagedStatic.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/raw_os_ostream.h>
#include <llvm/Linker/Linker.h>
int main(int argc, char *argv[]) {
using namespace llvm;
using namespace clang;
static const char* clangArgv [] = {"program", "-x", "c", "string-input"};
static const int clangArgc = sizeof (clangArgv) / sizeof (clangArgv[0]);
// C functions to be compiled (they could eventually be extremely large)
std::map<std::string, std::string> func2Source;
func2Source["getOne"] = "int getOne() {return 1;}";
func2Source["getTwo"] = "int getTwo() {return 2;}";
llvm::InitializeAllTargets();
llvm::InitializeAllAsmPrinters();
std::unique_ptr<llvm::Linker> linker;
std::unique_ptr<llvm::LLVMContext> context(new llvm::LLVMContext());
std::unique_ptr<llvm::Module> module;
/**
* add each C function to the same module
*/
for (const auto& p : func2Source) {
const std::string& source = p.second;
IntrusiveRefCntPtr<DiagnosticOptions> diagOpts = new DiagnosticOptions();
TextDiagnosticPrinter *diagClient = new TextDiagnosticPrinter(llvm::errs(), &*diagOpts); // will be owned by diags
IntrusiveRefCntPtr<DiagnosticIDs> diagID(new DiagnosticIDs());
IntrusiveRefCntPtr<DiagnosticsEngine> diags(new DiagnosticsEngine(diagID, &*diagOpts, diagClient));
ArrayRef<const char *> args(clangArgv + 1, // skip program name
clangArgc - 1);
std::unique_ptr<CompilerInvocation> invocation(createInvocationFromCommandLine(args, diags));
if (invocation.get() == nullptr) {
std::cerr << "Failed to create compiler invocation" << std::endl;
exit(1);
}
CompilerInvocation::setLangDefaults(*invocation->getLangOpts(), IK_C,
LangStandard::lang_unspecified);
invocation->getFrontendOpts().DisableFree = false; // make sure we free memory (by default it does not)
// Create a compiler instance to handle the actual work.
CompilerInstance compiler;
compiler.setInvocation(invocation.release());
// Create the compilers actual diagnostics engine.
compiler.createDiagnostics(); //compiler.createDiagnostics(argc, const_cast<char**> (argv));
if (!compiler.hasDiagnostics()) {
std::cerr << "No diagnostics" << std::endl;
exit(1);
}
// Create memory buffer with source text
std::unique_ptr<llvm::MemoryBuffer> buffer = llvm::MemoryBuffer::getMemBufferCopy(source, "SIMPLE_BUFFER");
if (buffer.get() == nullptr) {
std::cerr << "Failed to create memory buffer" << std::endl;
exit(1);
}
// Remap auxiliary name "string-input" to memory buffer
PreprocessorOptions& po = compiler.getInvocation().getPreprocessorOpts();
po.addRemappedFile("string-input", buffer.release());
// Create and execute the frontend to generate an LLVM bitcode module.
clang::EmitLLVMOnlyAction action(context.get());
if (!compiler.ExecuteAction(action)) {
std::cerr << "Failed to emit LLVM bitcode" << std::endl;
exit(1);
}
std::unique_ptr<llvm::Module> module1 = action.takeModule();
if (module1.get() == nullptr) {
std::cerr << "No module" << std::endl;
exit(1);
}
if (linker.get() == nullptr) {
module.reset(module1.release());
linker.reset(new llvm::Linker(module.get()));
} else {
if (linker->linkInModule(module1.release())) {
std::cerr << "LLVM failed to link module" << std::endl;
exit(1);
}
}
}
llvm::InitializeNativeTarget();
llvm::Module* m = module.get();
std::string errStr;
std::unique_ptr<llvm::ExecutionEngine> executionEngine(EngineBuilder(std::move(module))
.setErrorStr(&errStr)
.setEngineKind(EngineKind::JIT)
.setMCJITMemoryManager(std::unique_ptr<SectionMemoryManager>(new SectionMemoryManager()))
.setVerifyModules(true)
.create());
if (!executionEngine.get()) {
std::cerr << "Could not create ExecutionEngine: " + errStr << std::endl;
exit(1);
}
executionEngine->finalizeObject();
/**
* Lets try to use each function
*/
for (const auto& p : func2Source) {
const std::string& funcName = p.first;
llvm::Function* func = m->getFunction(funcName);
if (func == nullptr) {
std::cerr << "Unable to find function '" << funcName << "' in LLVM module" << std::endl;
exit(1);
}
// Validate the generated code, checking for consistency.
llvm::raw_os_ostream os(std::cerr);
bool failed = llvm::verifyFunction(*func, &os);
if (failed) {
std::cerr << "Failed to verify function '" << funcName << "' in LLVM module" << std::endl;
exit(1);
}
#if 1
func->dump(); // Dump the function for exposition purposes.
// JIT the function, returning a function pointer.
void *fPtr = executionEngine->getPointerToFunction(func); ///// BAD function pointer!!!!
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
int (*funcPtr)();
*(int **) (&funcPtr) = *(int **) fPtr;
int v = (*funcPtr)();
std::cout << "return: " << v << std::endl;
#else // THIS DOES NOT WORK EITHER:
// JIT the function, returning a function pointer.
uint64_t fPtr = executionEngine->getFunctionAddress(funcName); ///// BAD function pointer!!!!
if (fPtr == 0) {
std::cerr << "Unable to find function '" << funcName << "' in LLVM module" << std::endl;
exit(1);
}
int (*funcPtr)();
*(int **) (&funcPtr) = *(int **) fPtr;
int v = (*funcPtr)();
std::cout << "return: " << v << std::endl;
#endif
}
}
Can anyone help me pin-point the problem?
(I'm running this in linux-ubuntu 15.04)
This assignment is incredibly messed up:
*(int **) (&funcPtr) = *(int **) fPtr;
Not only does it violate strict-aliasing to write an int* and then use it as a function pointer on the next line, but a data pointer is often not large enough to hold an entire code pointer.
The safe approach is either
memcpy(funcPtr, fPtr, sizeof funcPtr);
or
funcPtr = reinterpret_cast<decltype(funcPtr)>(fPtr);
I am attaching the minimal code below. The problem is with static string object that is leaking memory. I think the problem is with the string object not being initialized properly. The program runs fine in Debug mode but crashes in the Release mode.
I am using Windows 7 : 64bit - MS Visual Studio 2012
I have tried initializing the object with empty string but it did not solve the problem as suggested here
what to do if debug runs fine, but release crashes
I enabled "Treating warnings as Errors" also did not help as there are no warning as suggested by the following post
what to do if debug runs fine, but release crashes
There were some other suggestions too like "static initialization order fiasco" but I do not think its related to my issue.
Any help is appreciated
main.cpp
//main.cpp
#include "MyParameters.h"
using namespace std ;
int main( int argc, char *argv[] )
{
try
{
cout << "MyParameters::m_outputDir: " << MyParameters::m_outputDir << endl ;
bool initialized = MyParameters::initialize( "myimo.xml" ) ;
cout << "MyParameters::m_outputDir: " << MyParameters::m_outputDir << endl ;
cout << "Terminating the application..." << endl ;
}
catch ( std::exception &e )
{
cout << e.what() << std::endl;
}
}
MyParameters.h
//MyParameters.h
#ifndef __MY_PARAMETERS_H
#define __MY_PARAMETERS_H
#include <string>
#include <iostream>
#include <QString>
class MyParameters
{
public:
static std::string m_outputDir; ///< output directory
static bool initialize( const QString &xmlFile );
private:
MyParameters();
};
#endif /* __MY_PARAMETERS_H */
MyParameters.cpp
//MyParameters.cpp
#include "MyParameters.h"
#include <QDir>
std::string MyParameters::m_outputDir ;
using namespace std ;
MyParameters::MyParameters()
{
}
bool MyParameters::initialize( const QString &xmlFile )
{
m_outputDir = QDir::current().absoluteFilePath( xmlFile ).toStdString(); // --> this crashes
//m_outputDir = "C:\\Dev\\" ; // --> works fine
cout << "m_outputDir: " << m_outputDir << endl ;
cout << "myparameters.xml file reading is complete" << endl ;
return true;
}