getting a SIGSEGV (segmentation fault) - c++

I'm creating a generic box with a template. Basically something like a queue or linked list. I keep getting a SIGSEGV for some reason and I can't figure it out. I take in an integer or a string from the user in main and then the constructor makes allocates memory for the generic box to exist, then using function inert_First (there are a lot more functions like insert_Mid, insert_last, delete_Mid etc) and it keeps telling me I'm accessing wrong memory but I don't know where ?
this is the class
template<class T>
class g_Box
{
int first,mid,last;
int no_Of_Ele;
int capacity;
T *ele;
public:
g_Box();
g_Box(int);
void insert_First(T);
};
this is the constructor
template<class T>
g_Box<T>::g_Box(){
first=-1, last=-1, mid=-1;
no_Of_Ele=0;
capacity=10;
T *ele = new T[capacity];
}
template<class T>
g_Box<T>::g_Box(int a){
first=-1, last=-1, mid=-1;
no_Of_Ele=0;
capacity=a;
T *ele = new T[capacity];
}
This is the insert_First
template<class T>
void g_Box<T>::insert_First(T a){
if(isFull()){
cout<<"The box is full";
}
else if(isEmpty()){
first=0; last=0; mid=(first+last)/2;
ele[0]=a;
no_Of_Ele++;
}
else{
T *ele2 = new T[capacity];
//T ele2[capacity];
for(int i=0; i<no_Of_Ele; i++){
ele2[i]=ele[i];
}
for(int i=0; i<no_Of_Ele; i++){
ele[i+1]=ele2[i];
}
ele[first]=a;
last++;
mid=(first+last)/2;
no_Of_Ele++;
delete[] ele2;
}
}
and this is the main
int main()
{
g_Box<int> g;
int data;
cin>>data
g.insert_First(data);
}

Related

Print elements of the stack from top to bottom with C++

I'm currently working with stack data structure in C++, and i'm trying to initialize the stack by using arrays.
Stack has a specific size and i want to print elements of the stack from top to bottom using for loop.
Here is my code:
#include <iostream>
using namespace std;
template<class T>
class Stack {
private:
int top, size;
T* stack = new T[size];
public:
Stack(int size) {
this->top = -1;
this->size = size;
}
void push(int data) {
if (top >= size - 1) {
return;
}
else {
++top;
stack[top] = data;
}
}
void pop() {
if (top < 0) {
return;
}
else {
--top;
}
}
void print() {
for (int i = top; i >= 0; i--) {
cout << stack[i] << endl;
}
}
};
int main() {
Stack<int> stack(20);
stack.push(12);
stack.push(3);
stack.push(4);
stack.push(7);
stack.print();
return 0;
}
After compiling i get all of my elements printed successfully, but unfortunately at the end the program throws an exception ntdll.pdb not loaded.
Thanks in advance.
The order of construction is wrong. The member variables are initialized before the constructor body is entered, so size contains an arbitrary value at that time it's read to determine the size of the array. Furthermore you forgot to delete the array.
To fix the initialization order, initialize the array in the constructor and add a destructor. In the following code I simply use std::unique_ptr which automatically deletes the array contained in it.
Furthermore it's preferrable to not use the same identifier for parameters and members; a prefix usually is added to member variables to avoid this
#include <memory>
...
template<class T>
class Stack {
private:
size_t m_size;
int m_top;
std::unique_ptr<T[]> m_stack;
public:
Stack(size_t size)
: m_stack(new T[size]), m_size(size), m_top(-1)
{
}
...

Segmentation fault: 11 in C++ IntVector

I'm attempting to implement an intvector in C++ and am getting a "Segmentation fault: 11" error. I understand this has something to do with memory management, and considering how new I am to C++ it could definitely be a pretty minor mistake. I debugged the code with valgrind and was given messages such as the following:
Use of uninitialized value of size 8, Invalid read of size 4,Conditional jump or move depends on uninitialized value(s).
My best guess is it has something to do with how I'm implementing the arrays. I originally had the arrays stored on the heap but changed it to the stack and still got the same error. I've already implemented an intvector in java, so I was attempting to use similar logic here, which perhaps is part of the issue.
#include <iostream>
#include "IntVector.h"
#include <cmath>
using namespace std;
int num_elements = 0;
int array_size = 0;
int expansion_factor;
void IntVector::expandArray(){
int tempArr[array_size*2];
for(int i =0;i<array_size;i++){
tempArr[i] = array[i];
}
array = tempArr;
array_size = array_size * 2;
}
void IntVector::add(int val){
int tempArr[array_size];
if(array_size == num_elements){
expandArray();
array[num_elements] = val;
}
else{
for(int i = 0;i<array_size;i++){
tempArr[i] = array[i];
}
tempArr[num_elements] = val;
array = tempArr;
}
num_elements++;
}
void IntVector::remove(int index){
}
int IntVector::get(int index) const{
return index;
}
void IntVector::removeLast(){
}
void IntVector::set(int index, int val){
}
std::string IntVector::toString()const {
return "";
}
IntVector::IntVector(int initial_size){
int* array = new int[initial_size];
}
IntVector:: ~IntVector(){
delete[] array;
}
int main(){
IntVector v(0);
v.add(5);
}
#ifndef INTVECTOR_H_
#define INTVECTOR_H_
using std::cout;
class IntVector {
private:
int* array;
int num_elements;
int array_size;
int expansion_factor;
void expandArray();
public:
void add(int val);
void remove(int index);
int get(int index) const;
void removeLast();
void set(int index, int val);
std::string toString() const;
IntVector(int initial_size);
~IntVector();
};
#endif
As mention in the comments, there are definitely some holes in your understanding of C++. Really when dealing with header files you should have a main.cpp, someotherfile.h, someotherfile.cpp. That just best practices to avoid redefinition errors.
There was quite a bit wrong with the way you accessed the private variable. If a class has a private( or even public) variable you don't have to redeclare it each time you want to change its value.
There were one or two major flaws with the way you expanded the vector. If the vector size is initialized to 0 then 0*2 is still 0 so you never actually increased the size. Secondly, when you set the original array = to the new array the new array was just a local array. This means that the memory wasn't actually allocated permanently, once the function ended the temparr was destroyed.
I know this was probably a lot but if you have any question feel free to ask.
main.cpp
#include "IntVector.h"
int main()
{
IntVector v;
IntVector x(10);
v.push(5);
v.push(5);
v.push(5);
v.push(5);
v.push(5);
v.print();
cout << endl;
x.push(5);
x.push(5);
x.push(5);
x.push(5);
x.push(5);
x.print();
return 0;
}
IntVector.h
#include <string>
#include <iostream>
using namespace std;
class IntVector {
private:
int *array;
int num_elements;
int array_size;
//int expansion_factor =; you would only need this if you plan on more than double the vector size
void expandArray(); //normally c++ array double in size each time they expand
public:
//Constructors
IntVector(); //this is a contructor for if nothing is called
IntVector(int initial_size);
//setters
void push(int val); //add
void pop(); //removelast
void remove(int index); //remove
void at(int index, int val); //set
//Getters
int at(int index);
//std::string toString(); I'm changing this to print
void print(); //will print the contents to the terminal
//Deconstructor
~IntVector();
};
IntVector.cpp
#include "IntVector.h"
//constructors
IntVector::IntVector() //no arguments given
{
array = new int[0];
num_elements = 0;
array_size = 0;
}
IntVector::IntVector(int initial_size)
{
array = new int[initial_size];
num_elements = 0;
array_size = initial_size;
}
void IntVector::expandArray()
{
int *tempArr;
if(array_size == 0){
array_size = 1;
tempArr = new int[1];
} else {
//make sure to allocate new memory
//you were creating a local array which was destroy after the function was completed
//using new will allow the array to exist outside the function
tempArr = new int[array_size * 2];
}
for (int i = 0; i < array_size; i++)
{
tempArr[i] = array[i];
}
//make sure to delete the old array otherwise there is a memory leak.
//c++ doesn't have a garbage collector
delete[] array;
array = tempArr;
array_size = array_size * 2;
}
void IntVector::push(int val)
{
num_elements++;
//checking if vector needs to increase
if (array_size <= num_elements)
{
expandArray();
array[num_elements-1] = val;
}
else
{
array[num_elements-1] = val;
}
}
void IntVector::remove(int index)
{
//not sure how to implment this becuase each element has to be a number.
}
int IntVector::at(int index)
{
return array[index];
}
void IntVector::pop()
{
num_elements = num_elements-1; //not really removing it from the "vector" but it won't print out again
}
void IntVector::at(int index, int val)
{
array[index] = val;
}
void IntVector::print()
{
for (int i = 0 ; i < num_elements; i++)
{
cout << array[i] << " ";
}
cout << endl;
}
IntVector::~IntVector()
{
delete[] array;
}
output
5 5 5 5 5
5 5 5 5 5
Hopefully, the comments help. I changed the name of the functions to better match the actual vecter class the already exists in C++. I think it's good to pick apart already defined functions like this because you get a better understanding of how they actually work and not just how to use them.
If you got any questions just leave a comment

I was just looking template and found this code in my book and this is showing segmantation fault?

This code gives the segmantation fault
Is the constructor called when assigning array to template specifically in this program?
Please explain in detail
if the constructor is called why is segmantation fault?
if not called isn't this the syntax error
#include <iostream>
using namespace std;
const int size=3;
template<class T>
class vector{
T *v;
public:
vector(){
v = new T[size];
for(int i=0;i<size;i++)
{
v[i]=0;
}
}
vector(T *a){
for (int i=0;i<size;i++)
{
v[i]=a[i];
}
}
T operator*(vector &v){
T sum=0;
for (int i=0;i<size;i++)
{
sum+=this->v[i]*v.v[i];
}
return sum;
}
void display(){
for (int i=0;i<size;i++)
{
cout << v[i] <<"\t";
}
}
};
int main()
{
int x[3]={1,3,5};
int y[3]={2,4,6};
vector<int> v1;
vector<int> v2;
v1=x;
v2=y;
v1.display();
cout<<endl;
v2.display();
return 0;
}
Apart from all the awful code, there's a problem with:
int x[3]={1,3,5};
...
vector<int> v1(x);
which calls:
template<class T>
class vector{
T *v;
...
public:
vector(T *a){
for (int i=0;i<size;i++)
{
v[i]=a[i];
}
}
...
because pointer v hasn't been assigned any memory.
So the first time through the for loop: v[0] = a[0]; will cause a segmentation fault.

Class of dynamically resizable C++ string array

I need to create a class called DynamicArray based on the given main.cpp file. However I cannot make it work. The program crashes. I believe it should be the constructor problem. Please see the following codes with comments:
main.ccp
#include <iostream>
#include <dynamicarray.h>
using namespace std;
int main()
{
DynamicArray* arr=new DynamicArray(ARRAY_SIZE);
for (int i=0; i<25; i++) {
arr->add("test");
}
for (int j=0; j<10; j++){
arr->remove();
}
delete [] arr;
arr=NULL;
return 0;
}
dynamicarray.h
#ifndef DYNAMICARRAY_H
#define DYNAMICARRAY_H
#define ARRAY_SIZE 5
#include <iostream>
using namespace std;
class DynamicArray
{
DynamicArray* darr;
int del;
int occSize;
int totSize;
public:
DynamicArray();
~DynamicArray();
DynamicArray(int);
void add(string);
void remove();
int totalSize();
int occupiedSize();
DynamicArray operator= (string);
DynamicArray operator= (int);
};
#endif // DYNAMICARRAY_H
dynamicarray.cpp
#include "dynamicarray.h"
DynamicArray::DynamicArray()
{
darr=new DynamicArray[ARRAY_SIZE];
del=0;
occSize=0;
totSize=ARRAY_SIZE;
}
DynamicArray::DynamicArray(int n){
darr=new DynamicArray[n];
del=0;
occSize=0;
totSize=ARRAY_SIZE;
}
DynamicArray::~DynamicArray()
{
delete [] darr;
darr=NULL;
}
//adding s to the next available slot in the array. When the array is full,
//add() will grow the array by another ARRAY_SIZE
void DynamicArray::add(string s){
if (occSize<totSize){
darr[occSize]=s;
occSize++;
}else{
totSize=totSize+ARRAY_SIZE;
DynamicArray* temp=new DynamicArray[totSize];
for (int i=0; i<occSize; i++){
temp[i]=darr[i];
}
darr=temp;
delete [] temp;
temp=NULL;
darr[occSize]=s;
occSize++;
}
}
//remove the element where the index is poining to in the array.
//when there are more than ARRAY_SIZE empty slots left, the delete()
//will shrink the array by another ARRAY_SIZE
void DynamicArray::remove(){
darr[del]=NULL;
del++;
occSize--;
if (del>5){
DynamicArray* temp=new DynamicArray[totSize-ARRAY_SIZE];
int j=del;
for (int i=0; i<occSize; i++){
temp[i]=darr[del];
j++;
}
darr=temp;
del=0;
delete [] temp;
temp=NULL;
}
}
//returning the current max capacity size of the array
int DynamicArray::totalSize(){
return totSize;
}
//returning the number of occupied slots in the array
int DynamicArray::occupiedSize(){
return occSize;
}
DynamicArray DynamicArray::operator= (string s){
*this=s;
return *this;
}
DynamicArray DynamicArray::operator= (int n){
*this=n;
return *this;
}
Of course it crashes, as in the constructor of DynamicArray you create new instances of DynamicArray which calls the constructor which in turn creates new instances of DynamicArray... This infinite recursion will lead to a stack overflow which crashes the program.
If the DynamicArray should by a dynamic array (or vector) of strings, then it should contain an "array" of strings, either std::string objects or of pointers. Like
class DynamicArray
{
private:
char** darr; // The actual array of data
...
};
DynamicArray::DynamicArray(int n)
{
darr = new char*[n];
...
}

operator new - Why operator new allocate array with negative value

template <class T> class Signal {
protected: int N; // length of array
public: T *sig;
Signal<T> fft();
}
template <class T> Signal<T> Signal<T>::fft() {
if (N==1) return *this;
if (N%2!=0)
cout<<"N is not power of 2";
else{
Signal<T> even;
even.sig=new T[N/2];
Signal<T> odd;
Signal<T> esig;
Signal<T> osig;
Signal<T> y;
y.sig=new T[N];
for (int i=0;i<N/2;i++) {
even.sig[i]=sig[2*i]; /* I failed here because new operator allocate array with negative value*/
}
esig= even.fft();
odd = even;
for (int i=0;i<N/2;i++) {
odd.sig[i]=sig[2*i+1];
}
osig= odd.fft();
/*not importan part*/
}
return y;
}
This is part of my class which represent Signal. I show only one one part of method fft which failed.
I got error Invalide allocation size 4294967295 in line where I put comment. When I debug I got that value for even.sig is 0x0062b9f8 {-842150451}.
How can I fix this and got array of not negative size.