Segmentation fault, when compiled with cmake and without cout - c++

I'm trying to make a list of objects (not using std::list) containing a pointer to the next and previous objects. For some reason the following code is throwing a segmentation fault, but when I commented out std::cout the code won't throw a segmentation fault, and when I don't compile with cmake, but with clang++. In both cases I'm using C++14.
#include <iostream>
class myListElement
{
myListElement *next;
double val;
public:
myListElement(int entry, myListElement *newPrev):val(entry), prev(newPrev){}
void setNext(myListElement *newPrev){prev = newPrev;}
};
class myList
{
myListElement *first,*last;
public:
myList(){}
~myList(){}
void push_back(int entry)
{
myListElement temp(entry,last);
if(last != nullptr)
{
last->setNext(&temp);
}
}
};
int main()
{
int n = 1000;
myList my_list;
//std::cout << "\ntest";
for(int i = 0; i < n; ++i)
{
my_list.push_back(i+1);
}
}
How can that be the case?
I'm sorry for the long code, but I couldn't find any part to delete without getting the Segmentation fault and keeping the sense of the program.
Thank you for every bit of help!

You do not initialize first and last with nullptr in the constructor.
You store pointers to local objects temp, their life is limited by push_back exit. You got dangling pointers and UB.
That is why STL exists and must be used. It is developed by the best C++ professionals and well tested.

Related

Program Gives An Error Every Time After Working Once

I'm attempting to implement my own array using pointers in C++. I'm using Visual Studio. I'm relatively new to C++, so if there is something obvious that I'm missing bear with me. But when I run it the first time, it works as intended. However, the next time I run it, I get one of two errors. One of the errors is
Unable To Start Program, Access Denied.
"the path of the file"
Access Is Denied
The other one that comes up rarely is
main.cpp has triggered a breakpoint
I think it has something to do with a wrong use of pointers, however that doesn't explain why it works the first time. Here is the code:
In main.cpp:
#include <iostream>
#include <vector>
#include "linked_list.hpp"
#include "trie.hpp"
#include "stack.hpp"
#include "queue.hpp"
#include "array.hpp"
int main() {
data_structures::array arr(5);
arr.set(4, 1);
int fourth_index = arr.get(4);
std::cout << fourth_index;
}
In array.hpp:
#pragma once
namespace data_structures {
class array {
private:
int* start;
public:
array(int size) {
start = new int(0);
for (int i = 1; i < size; i++) {
*(start + i) = 0;
}
}
public:
void set(int index, int val) {
if (index == 0) {
start = new int(val);
} else {
*(start + index) = val;
}
}
int get(int index) {
return *(start + index);
}
};
}
The first time, I get the correct output:
1
Then the next time I get the error I stated above.
Try changing this line:
start = new int(0);
to:
start = new int[size];
new int(0) is initializing "start" as a pointer to just one int with a value of 0. Instead, you need to allocate the memory necessary to hold your array. I suspect you're running into issues because you're writing into memory that you haven't allocated yet.
As a side note, make sure to add a destructor and free your memory.
Well you must be right! It is a memory issue and the error message "main.cpp has triggered a breakpoint" on windows indicates corruption of the heap in this case! I didn't have access to the hpp files you used apart from array.hpp
Let's start with some memory issues that your code is making
While initializing your array you are only initializing a single integer. But you need multiple integers in the array when you say want an array of size 5, you need to declare 5 integers. So you should declare an entire memory space for that. I am using malloc for this.
int* start = (int *)malloc(size*sizeof(int))
Secondly in your code for set there is a logical error that would change your start pointer from the original array which should not be happening. Instead you should just change the value at start.
*start = val;

How to fix 'Segmentation fault' error in c++

I'm trying to learn how to use the gdb debugger to fix this sample code. When stepping through the debugger, I can see that the line 'mylist[i]->val = i;' is throwing the segmentation fault.
I think I understand what a segmentation fault is, but I don't understand how this line could be causing it. Do I need to allocate memory for the mylist vector? How would I do that? I thought that the vector was already initialized and ready in main(), but I'm not really sure.
I have tried using 'new' for each node in the mylist vector but that gave me a compile error.
node* mylist[i] = new node; //what I tried
mylist[i]->val = i;
mylist[i]->next = NULL;
//error message
error: array must be initialized with a brace-enclosed initializer
node* mylist[i] = new node;
My code
class node
{
public:
int val;
node* next;
};
void create_LL(vector<node*>& mylist, int node_num)
{
mylist.assign(node_num, NULL);
//create a set of nodes
for (int i = 0; i < node_num; i++)
{
mylist[i]->val = i; //error happens here
mylist[i]->next = NULL;
}
... (relevant section of main() below)
int main(int argc, char ** argv)
{
const int NODE_NUM = 3;
vector<node*> mylist;
create_LL(mylist, NODE_NUM);
The actual error shown is "Segmentation fault (core dumped)"
When I print mylist right before the error line it shows
$1 = std::vector of length 3, capacity 3 = {0x0, 0x0, 0x0}
I am still learning c++ so I might be missing something really basic.
I would really appreciate any help. Thanks!
For starters, it's better if you hide variables inside a class. If you're not going to, the convention is to use a struct. It's also good practice to provide some constructor in that case, and maybe with default values:
class node
{
int val;
node* next;
public:
node(int v= 0, node* n= nullptr) : val(v), next(n) {}
};
Note the use of nullptr instead of NULL. Using the latter is a bad practice in c++.
The problem is that you can't use positions on a std::vector if they have not been allocated. When you do mylist[i]->val = i; you're in the lands of undefined behaviour.
You need first to push_back() or emplace_back() into a std::vector. So it's size() grows as it puts your data at the end (the back) of the vector. You could also use other methods, like reserve(). While push_back() pushes node* elements on your list, emplace_back() would construct them in place with no copy (no difference with raw pointers, but you can use a vector<node> instead of vector<node*> which is more straightforward.
// create a set of nodes
void create_LL(vector<node>& mylist, int node_num)
{
for (int i = 0; i < node_num; i++) {
mylist.emplace_back(i, nullptr); // calls node::node(i, nullptr) and inserts it at the end of the vector
}
or
// create a set of nodes
void create_LL(vector<node*>& mylist, int node_num)
{
for (int i = 0; i < node_num; i++) {
mylist.emplace_back(new node(i, nullptr));
}

How to avoid a destructor being called twice in C++?

I'm testing out a class representing an dynamic array data structure I made for myself as practice with the language, but I ran into a problem where the destructor is called twice over, causing a heap corruption error.
So far, I have attempted to comment out some of the delete words. However, this leads to undefined behavior.
#include <iostream>
#include "windows.h"
#include <vector>
template<typename T> class Spider {
private:
T** pointer;
int maxSize;
int lengthFilled;
public:
//default constructor
Spider()
{
pointer = new T * [1];
maxSize = 1;
lengthFilled = 0;
}
//destructor
~Spider()
{
for (int i = 0; i < lengthFilled; i++)
{
pop();
}
delete[] pointer;
}
//Pushes an object in
void push(T thing)
{
if (lengthFilled == maxSize)
{
increaseSize();
}
T* thinggummy = &thing;
//then save its pointer in the functional array
pointer[lengthFilled] = thinggummy;
lengthFilled++;
}
//pops the array
void pop()
{
delete pointer[lengthFilled-1];
setSize(lengthFilled - 1);
lengthFilled--;
}
}
int main()
{
Spider<Spider<int>> test((long long)1);
for (int i = 0; i < 2; i++)
{
test.push(Spider<int>());
test.get(i).push(2);//this is implemented in the actual code, just omitted here
std::cout << test.get(i).get(0);
std::cout << "push complete\n";
}
system("pause");
return 0;
}
The expected results for this program should be:
2
push complete
2
push complete
Press any key to continue...
Instead, I get an critical error code in the debug log of "Critical error detected c0000374".
There are two issues here:
Like WhiteSword already mentioned, you are taking the address of a local variable when you do T *thinggummy = &thing. That is going to cause trouble since that address will be invalid as soon as you leave scope (unless maybe T resolves to a reference type).
You call delete on the things in the pointer array. However, these were not allocated via new. Instead they are just addresses of something. So you are trying to free something that was never allocted.

C++ Segmentation Fault From Null Pointer Solution?

I'm getting a segmentation fault on this program, and I know it has something to do with a null pointer being dereferenced, but I'm not exactly sure which one is causing the error. I'm just not certain as to how to fix the error while maintaining the purpose of the original program - it will compile, but at runtime I get the segfault I was just talking about.
main:
#include "link.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
link * head_pointer = new link(NULL, NULL) ;
for (int i = 0; i < 10; i++) {
string new_string;
getline(cin, new_string);
string* pointer_to_input = new string(new_string);
link * current_link = new link(head_pointer, pointer_to_input );
head_pointer = current_link;
}
head_pointer -> printAll(*head_pointer);
return 42;
}
link:
#include <string>
#include <iostream>
#include "link.h"
using namespace std;
link::link(link * pointer_to_link, string * pointer_to_string)
{
next = pointer_to_link;
value = pointer_to_string;
}
link::~link() {
delete value;
delete next;
}
link * link::getNext() {
return next;
}
string * link::getString() {
return value;
}
int link::printAll(link link_to_print) {
cout << *link_to_print.getString() << endl;
if (link_to_print.next != NULL) {
return printAll(*link_to_print.getNext());
} else {
return 0;
}
}
Your destructor does look like an error, you shouldn't delete in destructor if you didn't allocate that in constructor:
link::~link() {
}
You should post your link.h to get more detailed explanation.
Without link.h it's not clear what else is wrong, however, there are also other problems:
link::printAll looks like a static method and should be called as: link::printAll(head_pointer);
you printAll should take by pointer, otherwise it it will create a copy of your link and delete it.
printAll has multiple issues as well. Probably it should have been something as follows:
void link::printAll(link *link_to_print)
{
if (!link_to_print)
return;
if (link_to_print->getString())
cout << *link_to_print->getString() << endl;
printAll(link_to_print->next);
}
and your main:
int main()
{
link * head_pointer = new link(NULL, NULL);
for (int i = 0; i < 10; i++) {
string new_string = str;
getline(cin, new_string);
string* pointer_to_input = new string(new_string);
link * current_link = new link(head_pointer, pointer_to_input);
head_pointer = current_link;
}
link::printAll(head_pointer);
return 42;
}
In short to avoid errors you shouldn't store pointers to strings in your link, you should just store strings themselves. Your links perhaps shouldn't assume ownership of other links:
struct link
{
link *next;
string value;
link(link *next, const std::string& value) : next(next), value(value) {}
link * getNext();
const std::string& getString() const;
static void printAll(link *link_to_print);
};
link * link::getNext() {
return next;
}
const string& link::getString() const {
return value;
}
void link::printAll(link *link_to_print)
{
if (!link_to_print)
return;
cout << link_to_print->getString() << endl;
printAll(link_to_print->next);
}
and your main:
int main()
{
link * head_pointer = new link(NULL, "");
for (int i = 0; i < 10; i++) {
string new_string;
getline(cin, new_string);
link * current_link = new link(head_pointer, new_string);
head_pointer = current_link;
}
link::printAll(head_pointer);
// TODO: now you need to walk head_pointer and delete all links manually.
return 42;
}
Once you learn how memory management works in general you should most likely redesign your link using some kind of smart pointer helper class, such as unique_ptr or shared_ptr. And off course, once you master linked list you should start using std::list.
link::printAll takes its argument by value, which has two important effects:
The argument inside the function is a second link object created by making copies of the same value and next pointer.
The copy has automatic storage duration and is destroyed at the end of the function call.
Therefore, you have double frees going on. In particular, both the copy made in the recursive call and the sub-link of the original link share the same value pointer, and both try to delete it. The second deletion causes undefined behavior.
The solution is to respect the rule-of-three and not allow shallow copies of raw pointers. There are two possible approaches for managing objects owned by pointer:
Write a copy constructor to go with your destructor, so the two deletes mentioned above act on two different copies of the value.
OR
Use a smart pointer, such as std::shared_ptr, so you don't have to write a destructor by hand at all.
Note that you need a pointer to implement the connection between objects in the linked list, but you do not need a pointer to store the data. Having a data member of type std::string, instead of std::string *, would be just fine and do the right thing when copied (It makes sense to think of std::string as a smart pointer to an array of characters, that just happens to also have some extra string-manipulation functions tacked on).

why does "a->content" give me a address instead of a value?

now i have been making games for a few years using the gm:s engine(tho i assure you i aint some newbie who uses drag and drop, as is all to often the case), and i have decided to start to learn to use c++ on its own, you know expand my knowledge and all that good stuff =D
while doing this, i have been attempting to make a list class as a practice project, you know, have a set of nodes linked together, then loop threw those nodes to get a value at a index, well here is my code, and i ask as the code has a single major issue that i struggle to understand
template<class type>
class ListNode
{
public:
type content;
ListNode<type>* next;
ListNode<type>* prev;
ListNode(type content) : content(content), next(NULL), prev(NULL) {}
protected:
private:
};
template<class type>
class List
{
public:
List() : SIZE(0), start(NULL), last(NULL) {}
unsigned int Add(type value)
{
if (this->SIZE == 0)
{
ListNode<type> a(value);
this->start = &a;
this->last = &a;
}
else
{
ListNode<type> a(value);
this->last->next = &a;
a.prev = this->last;
this->last = &a;
}
this->SIZE++;
return (this->SIZE - 1);
}
type Find(unsigned int pos)
{
ListNode<type>* a = this->start;
for(unsigned int i = 0; i<this->SIZE; i++)
{
if (i < pos)
{
a = a->next;
continue;
}
else
{
return (*a).content;
}
continue;
}
}
protected:
private:
unsigned int SIZE;
ListNode<type>* start;
ListNode<type>* last;
};
regardless, to me at least, this code looks fine, and it works in that i am able to create a new list without crashing, as well as being able to add elements to this list with it returning the proper index of those elements from within the list, however, beyond that the problem arises when getting the value of a element from the list itself, as when i ran the following test code, it didn't give me what it was built to give me
List<int> a;
unsigned int b = a.Add(313);
unsigned int c = a.Add(433);
print<unsigned int>(b);
print<int>(a.Find(b));
print<unsigned int>(c);
print<int>(a.Find(c));
now this code i expected to give me
0
313
1
433
as that's what is been told to do, however, it only half does this, giving me
0
2686684
1
2686584
now, this i am at a lost, i assume that the values provided are some kind of pointer address, but i simply don't understand what those are meant to be for, or what is causing the value to become that, or why
hence i ask the internet, wtf is causing these values to be given, as i am quite confused at this point
my apologies if that was a tad long and rambling, i tend to write such things often =D
thanks =D
You have lots of undefined behaviors in your code, when you store pointers to local variables and later dereference those pointers. Local variables are destructed once the scope they were declared in ends.
Example:
if (this->SIZE == 0)
{
ListNode<type> a(value);
this->start = &a;
this->last = &a;
}
Once the closing brace is reached the scope of the if body ends, and the variable a is destructed. The pointer to this variable is now a so called stray pointer and using it in any way will lead to undefined behavior.
The solution is to allocate the objects dynamically using new:
auto* a = new ListNode<type>(value);
Or if you don't have a C++11 capable compiler
ListNode<type>* a = new ListNode<type>(value);
First suggestion: use valgrind or a similar memory checker to execute this program. You will probably find there are many memory errors caused by dereferencing stack pointers that are out of scope.
Second suggestion: learn about the difference between objects on the stack and objects on the heap. (Hint: you want to use heap objects here.)
Third suggestion: learn about the concept of "ownership" of pointers. Usually you want to be very clear which pointer variable should be used to delete an object. The best way to do this is to use the std::unique_ptr smart pointer. For example, you could decide that each ListNode is owned by its predecessor:
std::unique_ptr<ListNode<type>> next;
ListNode<type>* prev;
and that the List container owns the head node of the list
std::unique_ptr<ListNode<type>> start;
ListNode<type>* last;
This way the compiler will do a lot of your work for you at compile-time, and you wont have to depend so much on using valgrind at runtime.