I'm running into an irritating problem where my program keeps crashing if I try to reference a private variable that I have created in one of my classes. I can't figure out where I am going wrong. Here is the class that calls the class that crashes:
#include <stack>
#include <fstream>
#include <ostream>
#include <cstdlib>
#include <string>
#include <set>
#include "schemeList.cpp"
using namespace std;
class dataLog
{
public:
stack<string> commands;
set<string> domain;
processor tokens;
int nextToken;
schemeList * s;
dataLog(stack<string> s, ofstream * out, processor p, int location)
{
commands = s;
tokens = p;
nextToken = location;
commands.push("<Query List>");
commands.push(":");
commands.push("Queries");
commands.push("<Rule List>");
commands.push(":");
commands.push("Rules");
commands.push("<Fact List>");
commands.push(":");
commands.push("Facts");
commands.push("<Scheme List>");
commands.push(":");
commands.push("Schemes");
checkNext();
}
void checkNext()
{
for(int i = 0; i < tokens.tags.size(); i++)
{
if(commands.top().compare(tokens.tags[i].getName())!=0)
{
if(commands.top().find("<")==0)
{
if(commands.top().compare("<Scheme List>")==0)
{
int output = (*s).process(i, tokens, domain); string hi = (*s).toString();
}
}
}
commands.pop();
}
}
};
This class creates an object of my SchemeList class, which is written out as follows:
#include "schemes.cpp"
#include <cstdlib>
#include <string>
#include <set>
using namespace std;
class schemeList
{
private:
string success;
public:
int process(int number, processor p, set<string> domain)
{
success = "HELLO";
return 13;
}
string toString()
{
return success;
}
};
As soon as I get to line 15 success = "HELLO";, the program crashes with the message
Unhandled exception at 0x00E48B66 in lab2.exe: 0xC0000005: Access violation reading
location 0xCCCCCCE4.
I am using Microsoft Visual Studio Express 2012 for Windows Desktop.
First off, the variable schemeList * dataLog::s is never initialized, so accessing it is undefined behavior, which leads to the crash. Most likely calling process on a dangling pointer and attempting to write into some memory you don't own.
Second, don't #include "schemeList.cpp". You're not supposed to include cpp files. Rather, separate declarations & implementations and include a header.
You have not initialized dataLog::s. When you call (*s).process(i, tokens, domain), you get undefined behavior.
Firstly, you're apparently including source code files in headers. This will likely break the one definition rule and go horribly wrong.
Secondly, 's' is not a very good name for a class member. It makes it almost impossible to find uses of it.
Thirdly, I can see nowhere in your code that initialises s. I can see where it gets referenced OK, but as it hasn't been initialised, the effect of dereferencing is undefined, and with luck will merely crash your program, which looks like what is happening.
Related
I have to calculate the longest prefix string in the program. I am using c++ for this and I don't actually know extensively about vector and its functions.
The code is:
#include <iostream>
#include <vector>
#include <string.h>
using namespace std;
class Solution {
public:
void longestCommonPrefix(vector<string>& strs)
{
string ans;
strs.size(); //no of rows
strs.push_back("flower");
strs.push_back("flower");
string one=strs[0];
string two=strs[1];
int oneL=one.length();
int twoL=two.length();
int min=oneL<twoL?oneL:twoL;
for(int i=0;i<min;i++)
{
char temp=one[i];
if(temp==two[i] )
ans=ans+temp;
}
}
};
This displays an error of winMain and I do understand it must be related to the main function but the problem is I cannot put nain() function here else it displays an error again. Thus, I cannot put a main function and I if I don't I face an error.
Help me out stackmates.
Shortened code I wrote for learning purposes. Still the way it is, it doesn't work properly.
Removing last line (&&) it works OK, but with it, code doesn't reach line noted as ##, expressing
segmentation error, after the "BazOnly" text displayed.
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
namespace nek{
class Baz{
int num;
std::string str;
public:
Baz(){cout<<"BazOnly"<<endl;}
string setstr(string& val){
//str.assign(val);
num= 7;
}
};
}
namespace drg{
class Deriv: nek::Baz{
public:
Deriv(char ch){cout<<"DerivChar"<<endl;}
};
};
int main(){
nek::Baz b;
string priv{"zik"};
b.setstr(priv);
cout<<"Passed here"<<endl; //##
drg::Deriv dc{'A'}; // &&
}
Compiled with g++ (option std=gnu++11), Ubuntu 16 on Virtual Box.
Question is what could be the reason for such behavior ?
string setstr(string& val){
//str.assign(val);
num= 7;
}
This method is declared as returning a std::string, but nothing actually gets returned from it. This is undefined behavior.
Most modern C++ compilers will warn you about this. If yours' did, this is an example of why you cannot ignore warning messages from your compiler, even if it did successfully compile your code.
Here's a minimal reproducible example of what I'm trying to accomplish:
I'm trying to set up a standard vector that will contain a list of all the possible operations my program can use. These operations are defined using my class Option, which is defined in my classes.cpp file. I want it to be set initially in my main.cpp file, but it should be usable in my setter.cpp file, in which I fill the vector.
Here is my code:
Main.h
#pragma once
#include <vector>
#include "classes.h"
extern std::vector<Option*> OPTIONS;
Main.cpp
#include <iostream>
#include <vector>
#include "classes.h"
#include "setter.h"
std::vector<Option*> OPTIONS = {};
int main()
{
initOptions(); //function from setter.cpp
OPTIONS[0]->pFunc(); // EXCEPTION at 0xCCCCCCCC in Main.exe: 0xC0000005: Acccess infraction when executing 0xCCCCCCCC.
return 0;
}
setter.h
#pragma once
void foo();
void initOptions();
setter.cpp
#include <iostream>
#include <string>
#include "Main.h"
void foo()
{
std::cout << "Hello world :)" << std::endl;
}
void initOptions()
{
OPTIONS = {
&Option("Test String", &foo)
};
}
classes.h
#pragma once
#include <string>
struct Option
{
std::string name;
void (*pFunc)();
Option(std::string n, void (*pF)()) : name(n), pFunc(pF) {};
};
I'm using Visual Studio 2019, all Main and setter files are in the same project, but classes.h is in another one (I know maybe this is not the most efficient way of doing things, but this is one of my first "interesting" projects and I'm trying to experiment a bit).
It compiles just fine, but when I execute it throw the exception: EXCEPTION at 0xCCCCCCCC in Main.exe: 0xC0000005: Acccess infraction when executing 0xCCCCCCCC.. Using the inspection tool from VS I can see that the OPTIONS vector has one element, but it is empty (string is "" and function pointer is 0x00000000). Am I declaring the global vector wrong? Did I not link projects correctly? Thanks in advance!
P.D: I tried to minimize and translate my code (not native speaker), so if there is incorrect spelling it's probably my translation and not the actual code :P
I'm trying to use an map with string key, but it's not working and I couldn't figure out why.
I would like to have some help to understand C++ fundamentals about the usage of this so essential structure.
model.hpp
#pragma once
#include <map>
#include <utility>
#include <string>
#include <iostream>
#include "../prs/ast.h"
using namespace std;
using namespace ast;
typedef map<string, Variable> Map;
typedef pair<string, Variable> Element;
namespace model{
class Warehouse {
public:
Map stock;
Warehouse(){
Map* _stock = new Map();
stock = *_stock;
}
Variable* get(string id){
Map::iterator it = stock.find(id);
if (it != stock.end()){
return &(*it).second;
}
else {
return __define__(id);
}
}
Variable* __define__(string id){
Variable* defined = new Variable(id);
stock.insert(Element(id, *defined));
return defined;
}
};
static Warehouse* WAREHOUSE;
};
model.cpp
#pragma once
#include "model.hpp"
using namespace std;
namespace model {
Warehouse* WAREHOUSE = new Warehouse();
}
In this context, Variable is a project object defined in ast
namespace already tested, as well WAREHOUSE pointer is working accordingly, with class
initialized
The instruction stock.find(id) is throwing the mentioned error message: Segmentation fault (core dumped), what I suppose means stock isn't correct initialized.
What is exactly happening with stock initialization done at Warehouse constructor?
I understand that new keyword allocs the map and dereference its returned point would store the structure at stock Warehouse member attribute.
Am I misunderstand it?
WAREHOUSE is a static variable defined in a header. What this means is that every source file that includes that header gets its own copy of this variable, initialized to nullptr. Only one source file sets its own copy to a non-null value. Presumably, some other source file in the code not shown attempts to dereference its copy.
Make it
extern Warehouse* WAREHOUSE;
I have a class which has a few attributes like shown below, my problem is that when I remove or place the string s attribute before std::atomic<char*> atomic_input the program terminates with exception:
'std::logic_error'
what(): basic_string::_M_construct null not valid
Aborted (core dumped)
#include <string>
#include <atomic>
// In ui.cpp
class UI
{
private:
std::atomic<char*> atomic_input;
std::string s; /* this can be renamed, but removing or placing it
before the above field crashes the program */
};
// In main.cpp
#include "ui.cpp"
int main()
{
srand (time(NULL));
initscr(); /* start the curses mode */
UI* ui = new UI();
return 0;
}
The string attribute is not accessed within the program in any way, renaming it is possible. The reason why I have an atomic field is that the value is shared among several threads.
I have tried placing the string field in different lines within the class attributes, the program only crashes if the declaration is before the atomic_input.
What might be causing the problem? Is it something to do with how the classes in C++ should be defined?
Looks like I've found a solution.
std::atomic<char*> atomic_input not being initialized like seen below was causing the issue. I still don't know how the string variable was interfering with it.
My guess is that the compiler somehow interprets the string as a constructor for atomic_input. The error only occurs when atomic_input is accessed in runtime and not in the compilation.
#include <string>
#include <atomic>
// In ui.cpp
class UI
{
private:
std::atomic<char*> atomic_input{(char*)""};
// std::string s; /* Initializing the atomic char like above solved the problem */
};