I have the following code that when compiles with my test program gives me a segmentation fault, I hope you guys can help me with this. I am compiling on a gcc compiler using:

g++ a3test.cpp screen.cpp dtio.c -lncurses

screen.h header file:

extern "C" {
   #include "dtio.h"
}

class Field{
    public:
        virtual ~Field() {}
        virtual void display() = 0;
        virtual int edit() = 0;
        virtual bool editable() const = 0;
        virtual void *data() = 0;
        virtual Field *clone() const = 0;
};

class LField : public Field{
    private:
        int row_loc;
        int col_loc;
        int width_tot; 
        int index;
        char *initval;
        bool edib;
    
    public:
        LField(int row, int col, int width, const char *s = 0, bool editable = true);
        ~LField();
        void display();
        int edit();
        bool editable() const;
        void *data();
        Field *clone() const;
        LField& operator = (const LField & rhs);
        LField(const LField & source );
};

class Screen{
    private:
        Field *fields[50];
        int count;
        int last;
        
    public:
        Screen();
        int add(int row, int column, int width, const char * s = "", bool editable = true);
        int add(const Field &f);
        void display(bool clear = false);
        int edit(int *pfield = NULL, bool clear = false);
        Field *getField(int i);
        int remove(int i);
        Screen& operator += (const Field &temp);
        Screen(const Screen& pass); 		
        Screen& operator = (const Screen& pass); 	
        ~Screen();
};

The screen.cpp file:

#include <string>
#include <iostream>
#include <new>
using namespace std;
#include "screen.h"

//LField class functions
//Different intiailization calls
LField::LField(int row, int col, int width, const char *s, bool editable){
    //Checks for valid coords
    if(row < 0){
        row = 0;
    }
    if(row >= dtioRows()){
        row = dtioRows() - 1;
    }
    if(col < 0){
        col = 0;
    }
    if(col > dtioColumns()){
        col = dtioColumns() - 1;
    }
    //Checks for width and location
    if((col + width) > dtioColumns()){
        width = width - ((col + width) - dtioColumns());
    }
    if(strlen(s)){
        if(strlen(s) > width){
            initval = new char[width];
            for(int i = 0; i < width; i++){
                initval[i] = s[i];
            }
        }
        else{
            initval = new char[strlen(s) + 1];
            strcpy(initval, s);
        }
    }
    else{
        initval = NULL;
    }
    row_loc = row;
    col_loc = col;
    width_tot = width;
    edib = editable;
    index = 0;
}

LField& LField::operator = (const LField & rhs){
    if(&rhs != this){
       delete [] initval;
       initval = new char[strlen(rhs.initval) + 1];
       strcpy(initval, rhs.initval);
       row_loc = rhs.row_loc;
       col_loc = rhs.col_loc;
       width_tot = rhs.width_tot;
       edib = rhs.edib;
       index = rhs.index;
    }
    return *this;
}
LField::LField(const LField & source){
       initval = NULL;
       initval = new char[strlen(source.initval) + 1];
       strcpy(initval, source.initval);
       row_loc = source.row_loc;
       col_loc = source.col_loc;
       width_tot = source.width_tot;
       edib = source.edib;
       index = source.index;
}
void LField::display(){
    dtioDisplay(initval, row_loc, col_loc, width_tot);
}
int LField::edit(){
    int retval = 0;
    if(edib){
        retval = dtioEdit(initval, row_loc, col_loc, width_tot, &index);
    }
    else{
        dtioDisplay(initval, row_loc, col_loc, width_tot);
        retval = 0;        
    }
    return retval;
}
bool LField::editable() const{
    return edib;
}
void *LField::data(){
    return &initval;
}
Field *LField::clone() const{
    return new LField(*this);
}
LField::~LField(){
  delete [] initval;
}
// Screen class and its member functions
Screen::Screen(){
    count = 0;
    last = 0;
    for(int i = 0; i < 50; i++){
        fields[i] = NULL;
	}
}
int Screen::add(int row, int col, int width, const char * s, bool editable){ 
    int retval = 0;
    if(last < 50){
        fields[last] = new LField(row, col, width, s, editable);
        count += 1;
        last += 1;
        retval = count;
    }
    return retval;
}
int Screen::add(const Field &f){
    int retval = 0;
    if(last < 50){
        fields[last] = f.clone();
        count += 1;
        last += 1;
        retval = count;
    }
    return retval;
}
void Screen::display(bool clear){
    if(clear){
        dtioClear();
    }
    for(int i = 0; i < count; i++){
        fields[i]->display();
    }
}
int Screen::edit(int *pfield, bool clear){
    int key;
    int fld_idx;
    int done = 1;
    if(clear){
        dtioClear();
    }
    if(pfield != NULL){
        fld_idx = *pfield;
    }
    else{
        fld_idx = 0;
    }
    while(done){
        key = fields[fld_idx]->edit();
        if(key == UP){
            int counter = fld_idx;
            while(!fields[counter]->editable() && counter < last){
                counter++;
            }
            if(counter >= last){
                done = 0;
            }
            else{
                fld_idx = counter;
            }
            
        }
        else if(key == DOWN){
            int counter = fld_idx;
            while(!fields[counter]->editable() && counter > 0){
                counter--;
            }
            if(counter <= 0){
                done = 0;
            }
            else{
                fld_idx = counter;
            }
        }
        else if(key == TAB){
            int counter = fld_idx;
            while(!fields[counter]->editable() && counter > 0){
                counter--;
            }
            if(counter <= 0){
                done = 0;
            }
            else{
                fld_idx = counter;
            }
        }
        else if(key == ENTER){
            int counter = fld_idx;
            while(!fields[counter]->editable() && counter < last){
                counter++;
            }
            if(counter >= last){
                done = 0;
            }
            else{
                fld_idx = counter;
            }
        }
        else{
            done = 0;
        }
    }
    *pfield = fld_idx; 
    return key;
}
Field *Screen::getField(int i){
    if(i >= 0 && i <= last){
        return fields[i];
    }
    else{
        return NULL;
    }
}
int Screen::remove(int i){
    if(i >= 0 && i <= last){
        delete fields[i];
        for(int x = i; x < count; x++){
            fields[x] = fields[x + 1];
        }
        last -= 1;
        count-= 1;
    }
    return count;
}
Screen& Screen::operator += (const Field &temp){
 	add(temp); 	
    return *this; 
}

Screen& Screen::operator = (const Screen& pass){
    if(&pass != this){
        for(int i = 0; i < 50; i++){
            Field * copy; 		
            copy = fields[i]; 		
            delete copy; 		
            fields[i] = NULL;
        }
        for(int i = 0; i < pass.count; i++){
            Field * copy; 		
            copy = pass.fields[i]; 		
            fields[i] = copy;
        }
        count = pass.count;
        last = pass.last;
    }
    return *this;
}
Screen::Screen(const Screen & pass){
    for(int i = 0; i < 50; i++){
        Field * copy; 		
        copy = fields[i]; 		
        delete copy; 		
        fields[i] = NULL;
    }
    for(int i = 0; i < pass.count; i++){
       Field * copy; 		
       copy = pass.fields[i]; 		
       fields[i] = copy;
    }
    count = pass.count;
    last = pass.last;
}
Screen::~Screen(){
    for(int i = 0; i < 50; i++){
        delete fields[i];
    }
}

I have attached the other files I am using as well as the specification of what I had to do. I don't know why it gives me a segmentation fault but it appears to happen when a constructor gets called. Any help with this is really appreciated! Thank you!

Recommended Answers

All 2 Replies

compile it for debug then seg fault will procduce a core file. Use the debugger on the core file and it will tell you what line caused the problem. Click here for more info.

Your remove leaves a garbage duplicate copy of a pointer when you shuffle the array down 1 place.
This will cause havoc if you then try to delete it.

Why aren't you using std::string for your char arrays, and std::vector for your field array (vector has a remove, which would solve the above problem so nicely).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.