0

In my project, I have a structure Transaction with the below interface:

/**
 * Transaction interface
 */
struct Transaction
{
    Transaction () : signature(new char[20]), otherAcc(new char[20]), amount(0)
    {
    }

    Transaction (const Transaction &other)
    : signature(new char[20]),
    otherAcc(new char[20])
    {
        strcpy(signature, other.signature);
        strcpy(otherAcc, other.otherAcc);
    }

    Transaction& operator = (const Transaction &other)
    {
        if (&other != this)
        {
            // out with the old
            delete[] signature;
            delete[] otherAcc;

            // in with the new
            signature = new char[20];
            otherAcc = new char[20];
            strcpy(signature, other.signature);
            strcpy(otherAcc, other.otherAcc);
        }
        return *this;
    } 

    ~Transaction ()
    {
        delete[] signature;
        delete[] otherAcc;
    }

    char *signature;
    char *otherAcc;
    int amount;
};

I initialize an (admittedly sloppy) implementation of a linked list with pointers to transactions on different occasions:

/**
 * linked list interface
 */
template <class T>
struct node
{
    /**
     * constructs a node in of a linked list with the value provided
     * and a NULL next node
     */
    node (T initial_value) : value(initial_value), next(NULL), refs(1) {}

    /**
     * frees the memory
     * allocated in the linked list
     */
    void clear ()
    {
        clearList();
    }
    /**
     * frees all nodes as well as encapsulated values in the
     * linked list
     */
    void clearWithValue ()
    {
        if (this)
        {
            next->clearWithValue();
            if (value)
                delete value;
            delete this;
        }
    }

    T value;
    node<T> *next;
    unsigned refs;
    bool isFirst;

    private:
        /**
         * clears the rest of the list starting from the node at
         * which lear list was called
         */
        void clearList ()
        {
            if (this)
            {
                next->clearList();
                delete this;
            }
        }
    };

The initialization would look something like this, where otherAcc and signature are const char * passed in by a function:

    Transaction *new_trans = new Transaction;
    strcpy(new_trans->otherAcc, otherAcc);
    strcpy(new_trans->signature, signature);
    new_trans->amount = amount;
    data->transactions = new node<Transaction*>(new_trans);

I am getting a segmentation fault, which I have determined to be caused by a bad pointer allocation in one of the nodes in the linked list. One of the nodes has value = { 0x343536373839 }, which cannot be accessed because it is out of bounds, so the program segfaults. Is this problem something obvious related to memory errors I'm not seeing? I'm pretty new to this stuff and debugging these memory errors can be a real pain, so general debugging tips are also welcome.

Edit: After I run this and it segfaults in gdb:

(gdb) bt
#3  0x00000000004015a0 in operator<< (os=..., acc=...) at tester.cpp:483

which is in my program

os << walker->value->otherAcc;

where walker is of type node *

Edit: I added the copy constructor and assignment operator as is now reflected in the Transaction interface, but it did not solve the segfault problem.

ironicaldiction
  • 1,200
  • 4
  • 12
  • 27
  • If you run this in the debugger, it will tell you which line it seg-faulted on. Could you do that, and then tell us, please? – Oliver Charlesworth Apr 20 '14 at 10:44
  • Also, your `Transaction` class is seriously flawed; you should read up on the [*Rule of Three*](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) (or just use `std::string`, rather than trying to memory-manage raw char arrays). – Oliver Charlesworth Apr 20 '14 at 10:44
  • `0x343536373839` is the character string `"456789"`, which probably resonates with something else you're doing in code you haven't shown here. – mah Apr 20 '14 at 10:48
  • Re: your edit. Your code crashes in a part of your code that you *haven't* shown us. You should boil this 483-line monster down to a [minimal test-case](http://stackoverflow.com/help/mcve), and then post that. – Oliver Charlesworth Apr 20 '14 at 10:53
  • @OliCharlesworth, working on it now. Would you recommend editing this question or posting anew and removing this question? – ironicaldiction Apr 20 '14 at 11:06
  • A statement like `if (this)` in a method shows that you aren't really understanding a certain aspect of OO programming in C++, if you pardon my harsh judgement. If `this == null` you wouldn't be there in the first place... – laune Apr 20 '14 at 11:09

0 Answers0