Segfault in my stack implementation (C++) code, but cannot understand why - c++

To set the record straight, I am fairly new to C++ and most of my experience in programming is in Java. I'm writing an array based stack implementation and I cannot seem to read any of the data saved in my stack.
Objects can be pushed and this seems to function normally. Commenting out the top() operation yields a successful output of zero, which seems to tell me that I know the item is at least being added to the array.
However, reading the item, I get a segfault error. After a quick google or two, I learned that a segfault means that there is an operation accessing data it does not have access to. This leads me to think that my top() function does not have access to the array. It is a private member of the class, but my previous knowledge of OOP tells me that a class method should have access to all private variables.
Could anyone help point me in the right direction here? (Apologies if the documentation is a bit excessive for such a primitive data structure, let me know if it should be removed).
Thanks! Code is below:
#include <iostream>
using namespace std;
/*
Class: arrayStack()
A simple stack implemented with a single array.
Handles char objects.
*/
class arrayStack {
int length; //cap on stack length
int count; //Keeps track of which element in the array to pop from.
char array[]; //Hold data here
public:
/*
arrayStack()
Constructor used to create a stack object. No default constructor exists, the length (l) is a required argument as a parameter to create a stack.
l space is reserved in the array and count is set to -1, the int value required for an empty stack.
*/
arrayStack(int l)
{
char array[l];
length = l;
count = -1;
}
/*
push() -- return type void.
Method to add a desired char element (o) to the stack.
*/
void push(char o)
{
array[count] = o;
count++; //Increment the counter to accurately pull element from array.
}
/*
pop() -- return type char.
Method to remove an element from the stack. Element is pulled from the stack and returned.
*/
char pop()
{
//temp space to store pulled element before returning.
char temp;
temp = array[count];
//Replace popped element with null to reduce memory waste. Then decrement counter for proper functioning of the stack.
array[count] = '\0';
count--;
return temp;
}
/*
top() -- return type char.
Method which returns the top element of the function without deleting it from the stack. Useful for inspection and testing, but functionally very similar to pop().
*/
char top()
{
//temp space to store pulled element.
char temp;
temp = array[count];
return temp;
}
/*
isEmpty() -- return type boolean.
Method which checks the stack for elements. If there are no elements, the method returns true. If there exists one or more elements, the method will return false.
Method is very simple-- a simple check against the count (int) variable.
*/
bool isEmpty()
{
if (count == -1) {
return true;
} else {
return false;
}
}
/*
size() -- return type int.
Method which returns the number of elements in the stack.
*/
int size()
{
return count++;
}
};
int main() {
arrayStack stack(10);
stack.push('c');
cout << stack.top(); //SEGFAULT OCCURS HERE.
cout << stack.isEmpty();
return 0;
}

Your member array is still uninitialized:
arrayStack(int l)
{
char array[l];
length = l;
count = -1;
}
Here, you create a new array (which I doubt is legal anyway, since C++ doesn't support VLA's. It should probably be
arrayStack(int l)
{
array = new char[l];
length = l;
count = -1;
}
You also need to implement a destructor to delete the allocated memory. Which means you also need a copy constructor and copy assignment operator.

Related

How to create an auxiliary data structure to keep track of heap indices in a minheap for the decrease_key operation in c++

I think this is probably a trivial problem to solve but I have been struggling with this for past few days.
I have the following vector: v = [7,3,16,4,2,1]. I was able to implement with some help from google simple minheap algorithm to get the smallest element in each iteration. After extraction of the minimum element, I need to decrease the values of some of the elements and then bubble them up.
The issue I am having is that I want find the elements whose value has to be reduced in the heap in constant time, then reduce that value and then bubble it up.
After the heapify operation, the heap_vector v_h looks like this: v_h = [1,2,7,4,3,16]. When I remove the min element 1, then the heap vector becomes, [2,3,7,4,16]. But before we do the swap and bubble up, say I want to change the values of 7 to 4, 16 to 4 and 4 to 3.5 . But I am not sure where they will be in the heap. The indices of values of the elements that have to be decreased will be given with respect to the original vector v. I figured out that I need to have an auxiliary data structure that can keep track of the heap indices in relation to the original order of the elements (the heap index vector should look like h_iv = [2,4,5,3,1,0] after all the elements have been inserted into the minheap. And whenever an element is deleted from the minheap, the heap_index should be -1. I created a vector to try to update the heap indices whenever there is a change but I am unable to do it.
I am pasting my work here and also at https://onlinegdb.com/SJR4LqQO4
Some of the work I had tried is commented out. I am unable to map the heap indices when there is a swap in the bubble up or bubble down operations. I will be very grateful to anyone who can lead me in a direction to solve my problem. Please also let me know if I have to rethink some of my logic.
The .hpp file
#ifndef minheap_hpp
#define minheap_hpp
#include <stdio.h>
// #include "helper.h"
#include <vector>
class minheap
{
public:
std::vector<int> vect;
std::vector<int> heap_index;
void bubble_down(int index);
void bubble_up(int index);
void Heapify();
public:
minheap(const std::vector<int>& input_vector);
minheap();
void insert(int value);
int get_min();
void delete_min();
void print_heap_vector();
};
#endif /* minheap_hpp */
The .cpp file
#include "minheap.hpp"
minheap::minheap(const std::vector<int>& input_vector) : vect(input_vector)
{
Heapify();
}
void minheap::Heapify()
{
int length = static_cast<int>(vect.size());
// auto start = 0;
// for (auto i = 0; i < vect.size(); i++){
// heap_index.push_back(start);
// start++;
// }
for(int i=length/2-1; i>=0; --i)
{
bubble_down(i);
}
}
void minheap::bubble_down(int index)
{
int length = static_cast<int>(vect.size());
int leftChildIndex = 2*index + 1;
int rightChildIndex = 2*index + 2;
if(leftChildIndex >= length){
return;
}
int minIndex = index;
if(vect[index] > vect[leftChildIndex])
{
minIndex = leftChildIndex;
}
if((rightChildIndex < length) && (vect[minIndex] > vect[rightChildIndex]))
{
minIndex = rightChildIndex;
}
if(minIndex != index)
{
std::swap(vect[index], vect[minIndex]);
// std::cout << "swap " << index << " - " << minIndex << "\n";
// auto a = heap_index[heap_index[index]];
// auto b = heap_index[heap_index[minIndex]];
// heap_index[a] = b;
// heap_index[b] = a;
// print_vector(heap_index);
bubble_down(minIndex);
}
}
void minheap::bubble_up(int index)
{
if(index == 0)
return;
int par_index = (index-1)/2;
if(vect[par_index] > vect[index])
{
std::swap(vect[index], vect[par_index]);
bubble_up(par_index);
}
}
void minheap::insert(int value)
{
int length = static_cast<int>(vect.size());
vect.push_back(value);
bubble_up(length);
}
int minheap::get_min()
{
return vect[0];
}
void minheap::delete_min()
{
int length = static_cast<int>(vect.size());
if(length == 0)
{
return;
}
vect[0] = vect[length-1];
vect.pop_back();
bubble_down(0);
}
void minheap::print_heap_vector(){
// print_vector(vect);
}
and the main file
#include <iostream>
#include <iostream>
#include "minheap.hpp"
int main(int argc, const char * argv[]) {
std::vector<int> vec {7, 3, 16, 4, 2, 1};
minheap mh(vec);
// mh.print_heap_vector();
for(int i=0; i<3; ++i)
{
auto a = mh.get_min();
mh.delete_min();
// mh.print_heap_vector();
std::cout << a << "\n";
}
// std::cout << "\n";
return 0;
}
"I want to change the values of 7 to 4, 16 to 4 and 4 to 3.5 . But I am not sure where they will be in the heap. The indices of values of the elements that have to be decreased will be given with respect to the original vector v. ... Please also let me know if I have to rethink some of my logic."
Rather than manipulate the values inside the heap, I would suggest keeping the values that need changing inside a vector (possibly v itself). The heap could be based on elements that are a struct (or class) that holds an index into the corresponding position in the vector with the values, rather than hold the (changing) value itself.
The struct (or class) would implement an operator< function that compares the values retrieved from the two vector locations for the respective index values. So, instead of storing the comparison value in the heap elements and comparing a < b, you would store index positions i and j and so on and compare v[i] < v[j] for the purpose of heap ordering.
In this way, the positions of the numerical values you need to update will never change from their original positions. The position information will never go stale (as I understand it from your description).
Of course, when you make changes to those stored values in the vector, that could easily invalidate any ordering that might have existed in the heap itself. As I understand your description, that much was necessarily true in any case. Therefore, depending on how you change the values, you might need to do a fresh make_heap to restore proper heap ordering. (That isn't clear, since it depends on whether your intended changes violate heap assumptions, but it would be a safe thing to assume unless there are strong assurances otherwise.)
I think the rest is pretty straight forward. You can still operate the heap as you intended before. For ease you might even give the struct (or class) a lookup function to return the current value at it's corresponding position in the vector, if you need that (rather than the index) as you pop out minimum values.
p.s. Here is a variation on the same idea.
In the original version above, one would likely need to also store a pointer to the location of the vector that held the vector of values, possibly as a shared static pointer of that struct (or class) so that all the members could dereference the pointer to that vector in combination with the index values to look up the particular member associated with that element.
If you prefer, instead of storing that shared vector pointer and an index in each member, each struct (or class) instance could more simply store a pointer (or iterator) directly to the corresponding value's location. If the values are integers, the heap element struct's member value could be int pointer. While each pointer might be larger than an index value, this does have the advantage that it eliminates any assumption about the data structure that holds the compared values and it is even simpler/faster to dereference vs. lookup with an index into the vector. (Both are constant time.)
One caution: In this alternate approach, the pointer values would be invalidated if you were to cause the vector's storage positions to change, e.g. by pushing in new values and expanding it in a way that forces it to reallocate it's space. I'm assuming you only need to change values, not expand the number of values after you've begun to use the heap. But if you did need to do that, that would be one reason to prefer index values, since they remain valid after expanding the vector (unlike pointers).
p.p.s. This technique is also valuable when the objects that you want to compare in the heap are large. Rather than have the heap perform many copy operations on large objects as it reorders the positions of the heap elements, by storing only pointers (or index values) the copying is much more efficient. In fact, this makes it possible to use heaps on objects that you might not want to copy at all.
Here is a quick idea of one version of the comparison function (with some class context now added).
class YourHeapElementClassName
{
public:
// constructor
explicit YourHeapElementClassName(theTypeOfYourComparableValueOrObject & val)
: m_valPointer(&val)
{
}
bool operator<(const YourHeapElementClassName & other) const
{
return *m_valPointer < *(other.m_valPointer);
}
...
private:
theTypeOfYourComparableValueOrObject * m_valPointer;
}; // YourHeapElementClassName
// and later instead of making a heap of int or double,
// you make a heap of YourHeapElementClassName objects
// that you initialize so each points to a value in v
// by using the constructor above with each v member.
// If you (probably) don't need to change the v values
// through these heap objects, the member value could be
// a pointer to a const value and the constructor could
// have a const reference argument for the original value.
If you had need to do this with different types of values or objects, the pointer approach could be implemented with a template that generalizes on the type of value or object and holds a pointer to that general type.

Infinite size Stack implementation using pointer to an array

I have been trying to make a infinite size stack using pointer to any int:
//in class:
int* stack;
//In constructor:
stack = new int();
//In deconstructor:
delete stack;
//In Push:
stack(++top) = element;
Is this declaration correct? Can I use this to make an infinite size stack? I run into error when I try to put elements into the stack using such pointer declaration.
It seems you are writing codes in C++? If no, please just ignore my post(face palm).
Firstly, the memory that could be assigned to a program is limited, i.e. no infinite size stack. In C++, there is BSS, Stack and Heap memory. In your case, you have used new operator to assign memory. This in fact effectively means you would like to get a piece of memory in the heap to store your value. Though the size of heap could be dynamically extended, its memory size is still not infinite.
Moreover, it seems what you would like to do in the constructor is to build up an int array with unlimited size. In fact, to declare an array, you may write new int[arraySize] to declare an int array of size, arraySize, in the heap. However, what you have written here is allocating a single int in the heap since the brackets you used are not square, but round. Unfortunately, to create an array, you need to declare its size first (for more details, you may search for stack array and dynamic array). So as to get rid of the size problem, you may use other data structures like std::vector and so forth for simple.
int* stack;
stack = new int();
These 2 statements are to have a pointer pointing to a single int stored in heap memory. Therefore, currently, the stack you make seems to be only able to store an int only.
As for the push function, top is the index of the top int in the stack?
One more thing, in case, what you want to make is creating a pointer to point an int array, and use the array as a stack. Then, you may think about the way to add memory, and have the deconstructor revised to be like this:
delete[] stack;
If you find difficulty in understanding my above paragraphs and have interest in learning more, perhaps you may firstly learn about stack & heap, then, the array declaration as well as its relationship with the memory allocation, followed by the knowledge about pointers.
I am a newbie. Hopefully, I haven't made any mistake in my answer.
First of all new int () creates only a single int not an array of integers therefore you can't do something like stack(++top) = element;.
If you want to create a dynamic array you should use int* stack = new int[size] and delete it with delete [] stack. As you can see the array has a limited size of size but you can resize it when it becomes full. There is no built-in way to resize the array but you can create a new dynamic array with bigger size and copy the old array into it and then remove the old array. But again the stack won't have infinite size since your memory is limited. If the allocation fails an exception will be thrown.
Below is a simple implementation of stack based on a dynamic array.
#include <stdexcept>
using namespace std;
class Stack{
public:
Stack (int _size = 20){
size = _size;
topIndex = 0;
stack = new int [size];
}
~Stack (){
delete [] stack;
}
void resize(){
int new_size = size*2;
int * new_stack;
// try{
new_stack = new int[new_size];
// } catch (std::bad_alloc&) {
// unsuccessful allocation
// }
for ( int i=0; i<size; ++i ){
new_stack[i] = stack[i];
}
delete [] stack;
stack = new_stack;
size = new_size;
}
void push(int element){
if (topIndex + 1 == size){
resize();
}
stack[topIndex++] = element;
}
int top(){
if ( topIndex <= 0 ){
throw std::out_of_range("stack is empty");
} else {
return stack[topIndex-1];
}
}
void pop(){
if ( topIndex <= 0 ){
throw std::out_of_range("stack is empty");
} else {
--topIndex;
}
}
private:
int * stack;
int size;
int topIndex;
};
int main(){
Stack stk;
for ( int i=0;i<50;++i ){
stk.push(i);
cout << stk.top() << endl;
}
for ( int i=0;i<50;++i ){
stk.pop();
cout << stk.top() << endl;
}
}
Note that this is all just for practice and the above implementation is error prone. You should almost always use built-in data structures in practical situations.

using size() to return the number of elements currently in my class (c++)

I'm currently writing this program and i have no idea how to use the size() method to return the number of values.
I have to create a class called IntSet, which represents a mathematical Set of Integers using the following data members:
A pointer to int that will point to a dynamically allocated array
which holds the values currently in in IntSet
An Int that holds the current size of the array (it will need
to be updated whenever the add() method because of array resize
An Int which holds the number of values currently in the
IntSet (it will need to be updated in the add() and remove()
methods
So far I've created a constructor and destructor and after doing the other methods I'm completely stumped on this one.
Header:
class IntSet
{
public:
IntSet(); //Constructor
~IntSet(); //Destructor
int size();
bool isEmpty();
bool contains();
void add(double number);
void remove(double number);
private:
int* ptr; //pointer to the array
int sizeOfArray; //current size of the array
int currentValue; //number of values currently in IntSet
}
and the main code so far:
#include <iostream>
#include "IntSet.hpp"
IntSet::IntSet()
{
sizeOfArray = 10;
currentValue = 0;
int* ptr = new int[10];
}
IntSet::~IntSet()
{
delete ptr;
}
So how would I even begin to use the size() method here?
if currentValue is indeed the number of values in the intSet as your comment claims, than size() can simply return currentValue.
Size is the number of element in your set.
At first, you should init it with value 0
Every you add new element successful, increase current size by 1
Every you remove element successful, decrease current size by 1
Method size(), you only need return current size of your set
From the specification you have given, currentValue holds the number of values in your set so you would define the following in your .cpp file.
int IntSet::size() const
{
return currentValue;
}
Keep in mind that you will need to increment/decrement this value whenever you add/remove an element to/from your set.

char array corruption in C++

I'm working on a project that makes me store an array of objects whose constructor is
Item(char* item, int itemType){
char temp[200];
for(int i = 0; i < 200; i++){
temp[i] = '\0';
if(item[i] != '\0'){
temp[i] = item[i];
}
}
_item = item;
_itemType = itemType;
_tweetIDs = NULL;
}
Don't worry about _tweetIDs, that's another functional part of my program and isn't related to my problem.
This array is stored within a class:
ItemList()
How this works is that the functional part of my program parses a line of input and puts it into the Item(char*, int) object. This is how it adds the line:
int addItem(char* item, int type){
char temp1[200];
for(int i = 0; i < 200; i++){
temp1[i] = '\0';
}
int j = 0;
while(item[j] != '\0'){
temp1[j] = item[j];
j++;
}
_items[_size] = Item(temp1, type);
_size++;
return _size;
}
Where _items is the Item() array and _size is a field that is incremented every time an Item() is added.
My issue comes when I have to print the contents of the list.
I have a method that does that:
void printList(){
for(int i = 0; i < 500; i++){
if(_items[i] != NULL){
cout << "[" << i << "] ";
_items[i]->printContents();
}
}
}
I tested printContents() in the constructor of Item() and tested printList in the addItem method and they both work when called within the class itself. The issue comes when I have to call the print method outside the class body.
In the main method, I create a List object:
List itemList;
The default constructor sets all members of the Item() array to NULL and initializes _size.
After adding a few Item() objects into the array (Which I confirmed is increasing in size through the debugger), I tried to print it out. When I call:
itemList.printList();
It gives me the right amount of indexes (And lines), but the char array is just a bunch of garbage. I used the debugger to try and find out where it went wrong. In the addItem() method, I called printList to check the array, and the output from that is fine. Then, I called itemList.printList() right after the last addItem() call, and it gave me garbage. In between the addItem() and itemList.printList(), the char array is lost or something along those lines.
Any idea what's going wrong? I'll give you any more code if you need it.
In your Item constructor, you are setting what I presume is a member _item as such:
_item = item;
This just assigns the pointer value of the location pointed to by item into _item. It does not actually copy the string!
The next time you go to read this location, it might be valid - chances are, though, it will be garbage, as you are seeing.
What you are looking for is a function like strcpy (as a side note, there's no need to do quite so much manual copying - just pass that pointer around and copy it once - in the Item constructor).
EDIT, to address your comment:
strcpy made your program crash because you are using it on unallocated memory.
You have to allocate memory for an array using new[] in c++
Take note on the lifetime of a variable.
If you declare temp1 as static array, then it will be destroyed immediately by the end of function addItem.
At the end, all object that refers to this memory location will be invalid.
And ....
If you want to pass a reference to an array do it this way:
Item(char** item, int itemType)
I'm imagining your definition of class Item minimally looks like this:
class Item
{
Item(char* item, int itemType);
private:
char *_item;
};
Your constructor must allocate memory for _item in order to make a copy of what gets passed in via the constructor. Failure to do that will inevitable result in memory problems and exceptions. Alternatively, you can use something like a vector of char.
In Item constructor you create local array char temp[200], you copy there what is pointed by char * item and then you don't use temp[200] any more. What's the point of doing that?
Later you assign passed pointer to _item member. The pointer points to local variable char temp1[200] in addItem(). When addItem() finishes then temp1 is destroyed and so _item in Item class points to garbage.
What you probably need to do is to allocate memory either statically in _item definition or dynamically using new (and then not forget to release it). I think the first solution will be safer for you. In the latter case you would also have to take care of copy constructor and assign operator. So, you need to change _item definition from char * _item to char _item[200], and then you can use strncpy:
Item(char* item, int itemType) {
strncpy(_item, item, 200);
}

Pointer Pointer Methods C++

I have two questions:
1) How can I make an array which points to objects of integers?
int* myName[5]; // is this correct?
2) If I want to return a pointer to an array, which points to objects (like (1)) how can I do this in a method? ie) I want to impliment the method:
int **getStuff() {
// what goes here?
return *(myName); // im pretty sure this is not correct
}
Thanks for the help!
How can I make an array which points
to objects?
int * myName[5]; /* correct */
If I want to return a pointer to an
array, which points to objects (like
(1)) how can I do this in a method?
Technically, you write this function:
int * (* getStuff() )[5] {
return &myName;
}
That returns a pointer to that array. However, you don't want to do that. You wanted to return a pointer to the first element of the array:
int ** getStuff() {
return myName; /* or return &myName[0]; */
}
That way, you can now access items as you want like getStuff()[0] = &someInteger;
Note that your code,
int* myName[5];
declares an array containing 5 values, each of which is a "pointer to int", which is what you asked.
However this being C++, that's all it does. As a Python scripter, that might cause you some surprises.
It does not give any of those 5 pointers sensible values, and it does not create any integers for them to point to.
If you put it in a function body, then it creates the array on the stack. This means that the array will cease to exist when the current scope ends (which, to put it simply, means when you get to the enclosing close-curly, so for example return does it). So in particular, the following code is bad:
int **myFunction() {
int *myArray[5];
return myArray;
} // <-- end of scope, and return takes us out of it
It might compile, but the function returns a pointer to something that no longer exists by the time the caller sees it. This leads to what we call "undefined behaviour".
If you want the array to exist outside the function it's created in, you could create one on the heap each time your function is called, and return a pointer, like this:
int **myFunction() {
int **myArray = new int[5];
return myArray;
}
The function returns a different array each time it's called. When the caller has finished with it, it should destroy the array, like this:
delete[] myArray;
otherwise it will never be freed, and will sit around using up memory forever (or when your program exits on most OSes).
Alternatively, you can use the keyword "static" to create an array with "global storage duration" (meaning that it exists as long as the program is running, but there's only one of it rather than a new one each time). That means the function returns the same array each time it's called. The caller could store some pointers in it, forget about it, call the function again, and see the same pointers still there:
int **myFunction() {
static int *myArray[5];
return myArray;
}
Note how similar this code is to the very bad code from earlier.
Finally, if you just want to create an array of integers, not an array of pointers to integers, you can do this:
int myArray[5] = { 1, 2, 3, 4, 5};
That actually creates 5 integers (meaning, it assigns space which can store the integer values themselves. That's different from the array of pointers, which stores the addresses of space used to store integer values).
It also stores the specified values in that space: myArray[0] is now 1, myArray[1] is 2, etc.
1) Correct - this is an array of 5 pointers to ints
2) You can return a pointer to an array of pointers to ints by returning a pointer to the first element of that array. This has two levels of indirection, so you need two asterisks. You can also return the array normally, since arrays automatically decay into pointers to their first elements.
int **getStuff() {
return myName; // 1
return &myName[0]; // 2
}
int **myName;
int **getStuff() {
int **array = new int*[5];
for (int i = 0; i < 5; i++)
{
int key = i;
array[i] = &key;
}
return array;
}
Steve Jessop, I think you meant:
int **myFunction() {
int **myArray = new int*[5];
return myArray;
}
This returns a heap array pointer (not pointer to its elements), testable and deletable. Nothing leaks.
template <class T>
T* newarray(int len)
{
T *a;
try
{
a = new T[len];
memset(a,0,len*sizeof(T));
return a;
}
catch (...)
{return 0;}
}
.
.
.
void foo()
{
float *f=0;
f=newarray<float>(1000000);
if(!f) return;
//use f
delete [] f;
}