Segmentation fault on class when declared as pointer - c++

So I’m in the process of creating an event style system, but this code breaks when I declare a connection as a pointer.
#include <iostream>
#include <chrono>
#include <thread>
using namespace std;
using namespace chrono_literals;
template<typename... Types>
struct Connection {
void Connect(void(*f)(Types...)) {
Callback = f;
}
void Fire(Types... Args) {
Callback(Args...);
}
private:
void(*Callback)(Types...);
};
int main() {
cout << boolalpha;
Connection<char>* event;
event->Connect([](char key){
cout << "Event fired!" << '\n';
cout << "Key: " << key << '\n';
});
event->Fire('a');
}
This code works when the connection isn’t a pointer, and instead of using the -> operator, I’d use use the regular . operator, but I’d like to declare them as pointers so I can use the -> .
One very strange thing to note is when I do something like this
Connection<char> e;
Connection<char>* event;
// ... rest of code
Then this actually runs, I don’t know why it’s like that.

You don't "declare a class as a pointer". That's not a thing. You have a class (which is a type), then you declare an instance of that class (i.e. an object). Optionally you can manage that object using pointers.
But you didn't actually create any instance. All you did was create a pointer, uninitialised, not pointing to anything, then tried to dereference it to use the object it points to… which doesn't exist.
There's no need for dynamic allocation here anyway; forget the pointer and just declare a nice Connection<Event>. Using pointers "because it looks nicer" is, to put it kindly, not the best way to write a C++ program.

Related

What is the purpose of declaring a function as a pointer?

I was looking through the source code of a project called CrossWindow-Graphics today when I saw an interesting function declaration. The code seemed to be declared as a function pointer. Here is a similar example I wrote.
#include <iostream>
using namespace std;
void (*Test())
{
cout << "Test Called!" << endl;
}
int main()
{
Test();
return 0;
}
My question is why does C++ allow this. I'd imagine it has something to do with function pointers. I remember that typedef is really just creating a variable and the name of the variable becomes the new type so I suppose this is just the same as creating a "variable" but it points to code. Even if that is the right idea, What is the purpose of that?
All you've really done here is add an extra pair of () that doesn't do anything.
We could write the same functin as
void* Test() { ... }
It's a function that returns a void*.
So the function should have a return statements where it returns a void pointer. Some compilers will warn about this as seen here.

How to use a unique_ptr after passing it to a function?

I just started learning the new C++ memory model:
#include <string>
#include <iostream>
#include <memory>
void print(unique_ptr<std::string> s) {
std::cout << *s << " " << s->size() << "\n";
}
int main() {
auto s = std::make_unique<std::string>("Hello");
print(std::move(s));
std::cout << *s;
return 0;
}
Right now calling cout << *s; results in a segfault, as it should. I understand why it happens. But I also would like to know if there's a way get back the ownership. I'd like to be able to use a value after passing it to a function.
If you don't want to transfer ownership of the owned object, then don't pass the unique_ptr to the function. Instead, pass a reference or a raw pointer to the function (in modern C++ style, a raw pointer is usually understood to be non-owning). In the case where you just want to read the object, a const reference is usually appropriate:
void print(const std::string&);
// ...
print(*s);

Why does my class std::vector member always throw a segfault?

I've searched endlessly on SE for a logical explanation for why this is happening. It is probably something very simple that I've overlooked, however I cannot spot it and would really appreciate some assistance with this.
Last week I implemented a class to read the output of a system call from a .ini file and then find and store the required information into custom objects that are then stored in a vector inside a Config class. It is a Singleton config class storing a unique_ptr for each instance of my custom class that is created.
The thing is, when I implemented this last week on my laptop, I had zero issues reading and writing to my member vector and was able to get it working exactly how I needed it. Since pulling to my desktop computer, this vector, and any STL container that I use as a member of my class, throws a segmentation fault when I try to do anything on it, even get it's size.
I've tried to shorten the code below to only include sections that actually use this vector. I have replaced my config with A, and custom class with T, and no matter where I try to use my member container, or any other test STL containers that I add to the class, I get a segfault.
For the record, I am using Qt with C++11.
Update: This example breaks on line 50 of c.cpp when debugging, and anywhere that tries to call the vector.
Debug points to this line in stl_vector.h
// [23.2.4.2] capacity
/** Returns the number of elements in the %vector. */
size_type
size() const _GLIBCXX_NOEXCEPT
/*-> this line */ { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); }
main.cpp
#include "c.h"
int main(int argc, char *argv[])
{
C *c = C::getInstance();
delete c;
return 0;
}
t.h - Class stores information from file
#include <string>
class T
{
public:
T();
bool Active();
std::string getA();
void setA(std::string);
private:
std::string a;
};
t.cpp
#include "t.h"
T::T()
{
}
bool T::Active()
{
if(a == "")
{
return false;
}
return true;
}
std::string T::getA()
{
return this->a;
}
void T::setA(std::string newa)
{
this->a = newa;
}
c.h - Class stores T objects and parses file for information
#include "t.h"
#include <QDebug>
#include <vector>
#include <algorithm>
#include <iostream>
#include <memory>
#include <sstream>
#include <fstream>
class C
{
public:
static C* getInstance();
private:
C();
static C* instance;
static bool init;
std::vector<std::unique_ptr<T>> t_list;
void readLines(const std::string&);
};
c.cpp
#include "c.h"
bool C::init = false;
C* C::instance = nullptr;
C::C()
{
system("echo this is a test command > a.ini");
instance->readLines("a.ini");
}
C* C::getInstance()
{
if(!init)
{
instance = new C;
init = true;
}
return instance;
}
void C::readLines(const std::string &path)
{
T* new_t;
std::ifstream file(path.c_str());
if(!file.is_open())
{
qDebug() << "Unable to open " << path.c_str();
}
std::ofstream o("test.txt");
std::string line;
while(std::getline(file, line))
{
// Split string before searching
std::stringstream ss(line);
std::string seg;
std::vector<std::string> split;
std::string left, right;
// Search patterns
size_t find_a = line.find("a");
size_t del = line.find(':');
if(find_a != std::string::npos)
{
o << "test_Size: " << t_list.size() << std::endl;
if(new_t->Active())
{
T* temp = new_t;
std::unique_ptr<T> move_t(temp);
t_list.push_back(std::move(move_t));
}
o << "test: " << t_list.size() << std::endl;
std::string n;
// Check if previous ahas any null elements
// Split string to find a
n = line.substr(line.find("a "));
n = n.substr(n.find(" ", +2));
new_t->setA(n);
}
else
{
continue;
}
}
// Add last a
T* t = new_t;
std::unique_ptr<T> move_t(t);
//t_list.push_back(std::move(move_t));
o << "a: " << t_list.back().get()->getA() << std::endl;
o << t_list.size() << std::endl;
o.close();
file.close();
}
UPDATE after code change:
I see two things now: One is that new_t in C::readlines is never initialized, so this could break when new_t->Active() is called a bit later in the function. However, I believe that the main problem you're running into is in C::C(), where it says
instance->readLines("a.ini");
At this point in the execution, C::instance is not yet initialized -- you're only just constructing the object that would later be assigned to it. Because of this, this in the readlines call is invalid, and any attempt to access object members will cause UB. This latter problem can be fixed by just calling
readLines("a.ini");
in which case the currently constructed object (that will later be instance) is used for this. I have no idea what you want to happen for the first, though, so all I can say is: If you want to have a vector<unique_ptr<T>>, you will have to create objects of type T with either new T() or (arguably preferrably) std::make_unique<T>() and put them in there.
I'll also say that this is a rather ugly way to implement a singleton in C++. I mean, singletons are never really pretty, but if you're going to do it in C++, the usual way is something like the accepted answer of C++ Singleton design pattern .
Old answer:
The problem (if it is the only one, which I cannot verify because you didn't provide an MCVE) is in the lines
T move_t = new_T;
std::unique_ptr<Adapter> ptr_t(&move_t); // <-- particularly this one
m_ts.push_back(std::move(ptr_t));
You're passing a pointer to a local object into a std::unique_ptr, but the whole purpose of std::unique_ptr is to handle objects allocated with new to avoid memory leaks. Not only will the pointer you pass into it be invalid once the scope surrounding this declaration is left, even if that weren't the case the unique_ptr would attempt to delete an object that's not on the heap at the end of its lifecycle. Both problems cause undefined behavior.
To me, it looks as though you really want to use a std::vector<T> instead of std::vector<std::unique_ptr<T>>, but that's a design issue you'll have to answer yourself.
Answering my own question here. I am trying to call a member variable from within the constructor of the object that holds it, so the vector I am trying to access is not yet instantiated and doesn't exist in memory. That is what causes the Segmentation fault to occur, I am trying to access memory that is not allocated yet, hence any call acting on any member of my C class was causing this issue.
I fixed this problem by adding a public function to the class that then calls the private readLines() function. I call that public function from the object that will take ownership of it, and since this occurs after it has been instantiated, the memory is accessible and the problem disappears.

C++ Dynamic Array Member Variable Assignment

I am having a problem with assigning new values to a dynamic int array that is a data member variable of the class IntersectionFlowRate(). I can initialize and print the values of the array inside the constructor. However, when I exit the constructor to the another class and then later call a function within the IntersectionFlowRate() class passing in variables to overwrite the initial values of the data member it will segmentation fault. I have debugged to find that overwriting the array is causing the seg fault. And that even attempting to access the dynamic array within one of its functions will seg fault.
My question is how can I edit the values of a dynamic int array member variable from within one of its functions i.e setArrayElement(int index, int x).
Here is some of my code. Sorry if I am unclear or missing something ridiculous. I have been stuck on this for hours.
#ifndef INTERSECTIONFLOWRATE_H
#define INTERSECTIONFLOWRATE_H
class IntersectionFlowRate
{
public:
IntersectionFlowRate();
~IntersectionFlowRate();
void setFlowCycle(int index, int flow);
private:
int* m_flowRateMotorCycle;
};
#endif
in the .h file ^
#include "IntersectionFlowRate.h"
#include <cstdlib>
#include <iostream>
#include <new>
using namespace std;
IntersectionFlowRate::IntersectionFlowRate()
{
const int SIZE = 4; //Constant for m_flowRates[] size
//DYNAMIC MEMORY DELETE LATER
m_flowRateMotorCycle = new int[SIZE];
for(int i = 0; i < SIZE; i++){
m_flowRateMotorCycle[i] = 0;
cout << m_flowRateMotorCycle[i] << endl;
cout << "WE GOT HERE" << endl;
}
}
void IntersectionFlowRate::setFlowCycle(int index, int flow){
cout << "INDEX: " << index << endl;
cout << "FLOW: " << flow << endl;
m_flowRateMotorCycle[index] = flow; //seg fault is here
}
I have another class that creates a pointer to a IntersectionFlowRate() object and then calls its setFlowCycle function passing in two VALID ints. With the debugging I was able pass 0 and 3 to the function setFlowCycle(0, 3) just fine and output those variables within the function.
#ifndef TRAFFICSIM_H
#define TRAFFICSIM_H
#include "IntersectionFlowRate.h"
using namespace std;
class TrafficSim
{
public:
TrafficSim(); //Default Constructor
TrafficSim(const char* file); //Constructor
~TrafficSim(); //Destructor
private:
IntersectionFlowRate* m_flowRate;
};
#endif
#include "TrafficSim.h"
#include "IntersectionFlowRate.h"
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
using namespace std;
TrafficSim::TrafficSim()
{
IntersectionFlowRate* m_flowRate = new IntersectionFlowRate();
m_flowRate->setFlowCycle(0, 3);
}
I replicated the error with this code. If no one else can I am completely unsure of what is possibly wrong anymore.
You are setting a local variable called m_flowRate, not the member variable m_flowRate of your TrafficSim class:
Instead of this:
TrafficSim::TrafficSim()
{
IntersectionFlowRate* m_flowRate = new IntersectionFlowRate();
m_flowRate->setFlowCycle(0, 3);
}
It should be this:
TrafficSim::TrafficSim()
{
m_flowRate = new IntersectionFlowRate();
m_flowRate->setFlowCycle(0, 3);
}
But overall, it not need be a pointer. It could be an object member within your class. That would cut down on the pointer usage a bit:
class TrafficSim
{
public:
TrafficSim(); //Default Constructor
TrafficSim(const char* file); //Constructor
private:
IntersectionFlowRate m_flowRate;
};
Then:
TrafficSim::TrafficSim()
{
m_flowRate.setFlowCycle(0, 3);
}
As to your question as to how to incorporate usage of std::vector in your class, here is a code sample of the IntersectionFlowRate class, rewritten using vector:
Vector sample
Also, another source of problems is that your classes fail to follow the Rule of 3 when you have pointers to dynamically allocated memory in your class.
Using std::vector takes care of this automatically, but if you insist on using pointers, you need to adhere to the directions at the link posted.
Yes, use a std::vector, it is much simpler, and it is a template so it also pretty fast and works any type (best for primitive types or pointers to objects) , and it also has boundary checking and other useful things.
If you need fast array-like access then you could use std::map which associates a key with a value, like so
std::map<UINT, YourClass*> m_mapIDs_to_YourClass;
When you first start using stl containers they might seem a little strange, but after a short while you cannot do without them, luckily they have been part of the C++ standard for some time now.
Boundary check for both these containers can be done by comparing your iterator to mapYourMap.end(), if they are equal you have passed the last element and trying to access data through the iterator will cause an exception.
Example for std::vector (if vecInt is a vector< int >):
vector<int>::iterator it = vecInt.begind();
if (it == vecInt.end()) return; // vector is empty
do { // runs through elememts until out of bound, useful for searching
i++
while (it != vecInt.end());

C++ geting error while using function inside class

I can't figure out why I get this error: "the function was not declared". I am still a newbie at programming, but I am trying my best to learn it!
so here is my code, I would be realy greatful if you could help me:
main:
#include <iostream>
#include <vector>
#include "szovegkezelo.h"
using namespace std;
int main()
{
string sz;
beolvas(sz);
kiir(sz);
return 0;
}
header:
#ifndef SZOVEGKEZELO_H_INCLUDED
#define SZOVEGKEZELO_H_INCLUDED
#include <iostream>
using namespace std;
class szovegkezelo {
protected:
string sz;
public:szovegkezelo
void beolvas(string &sz);
void kiir(string t);
};
#endif // SZOVEGKEZELO_H_INCLUDED
cpp:
#include "szovegkezelo.h"
#include <iostream>
void szovegkezelo::beolvas(string &sz)
{
getline(cin, sz);
}
void szovegkezelo::kiir(string t)
{
cout << "a beadott szoveg: " << t << endl;
cout << "a string hossza: " << t.size() << endl;
}
From what it looks like, you are trying to call a classes function (method) called 'beolvas' from 'main' but because it belongs to a class, you can't call it like that, you need to create an instance of that class and call the method on that instance, or make the function static and call it from the class.
Your first option is to create an instance of the class and then call the methods on the class like so:
int main()
{
string sz;
szovegkezelo szov;
szov.beolvas(sz);
svoz.kiir(sz);
return 0;
}
Your second option is to make the functions in your class static, this way they will not need an instance of the class to be called:
int main()
{
string sz;
szov::beolvas(sz);
svoz::kiir(sz);
return 0;
}
static void szovegkezelo::beolvas(string &sz)
{
getline(cin, sz);
}
static void szovegkezelo::kiir(string t)
{
cout << "a beadott szoveg: " << t << endl;
cout << "a string hossza: " << t.size() << endl;
}
Been a while since I've done anything static in c++ so please correct me if I've done something wrong in the second option.
Your two or more data types... error comes from a misuse of...something...after that public access specifier.
Change this:
public:szovegkezelo
to this:
public:
If you're trying to make a constructor, it needs to be declared like any other function, minus the return type.
Your other error occurs because this function was declared improperly.
Other than that, you need to create an object before you can call the class's functions. Each object has it's own set of variables that the functions work on. I would seriously recommend reading a good beginner C++ OOP book.
Somewhere in main, you need to create an object:
szovegkezelo myObject;
Then, use it to call functions:
myObject.kiir (sz);
Finally, note that your data members should typically be declared with the private access specifier. protected has nothing to do with normal classes that are not inherited from.
couple of things :
1) In main you have not instantiated an object of szovegkezelo and you are trying to call beolvas . Compiler is looking for a free function beolvas whereas you have declared beolvas as member function
2) public:szovegkezelo is not right if you are looking for a default constrcutor that does nothing don't have that line else if you need to do something specific with default construct declare it as szovegkezelo() in header.
3) as mentioned in comments it is not a good practice to put
using namespace std in header files or any using namespace