Search code examples
c++segmentation-faultmultimapcc

Segmentation fault with Sun c++ compiler


I have a class AccountMap in AccountMap.h and AccountMap.cpp. It reads stuff from a binary file (which is ok) and outputs stuff. It runs perfectly fine on g++ compiler but gives me a seg fault on sun c++ CC compiler when I use new operator for the 10 iteration in one of my function. If I ignore the seg fault it still outputs the correct thing. Here is my AccountMap.h:

#ifndef account_map
#define account_map

#include <iostream>
#include <map>
#include <cstring>
#include "Account.h"

using namespace std;

struct CompareCharArrays
{
    bool operator()(const char* a, const char* b) const //overloading () operator 
    {
        if((strcmp(a,b) < 0))
        {
            return true;
        }
        return false;
    }
};

class AccountMap
{
    public:
        ~AccountMap(); //destructor
        void loadData(const char *); //loads data from a  given file
        int countRecs(const char *); //counts total number of records in the given file
        void displayData(); //displays data


    private:
        multimap<const char *, Account, CompareCharArrays> accounts; //a multipmap
        Account** account_manager; //two-D array of accounts
        char** key_manager; //two-D array of keys
        int total_accounts; //total number of accounts
};

#endif

Here is my AccountMap.cpp function that causes seg fault:

void AccountMap::loadData(const char * file) //loads data from a  given file
{
    int num = countRecs(file); //total no of records in the file
    ifstream in(file, ios::in | ios::binary);
    if(!in)
    {
        cerr<<"File doesn't exist!"<<endl;
        exit(1);
    }
    this->account_manager = new (nothrow) Account*[num]; 
    if(this->account_manager == NULL)
    {
        exit(1);
    }
    this->key_manager = new (nothrow) char*[num]; //seg fault here during 10th iteration
    if(this->key_manager == NULL)
    {
        exit(1);
    }
    simplyfy_data acc;
    this->total_accounts = 0;
    while(in.read((char*)&acc, sizeof(simplyfy_data)))
    {
        this->account_manager[this->total_accounts] = new (nothrow) Account;
        if(this->account_manager[this->total_accounts] == NULL)
        {
            exit(1);
        }
        this->key_manager[this->total_accounts] = new (nothrow) char;
        if(this->key_manager[this->total_accounts] == NULL)
        {
            exit(1);
        }
        string date;
        int len = strlen(acc.dob);
        for(int i = 0; i < len; i++)
        {
            date.push_back(acc.dob[i]);
        }
        account_manager[this->total_accounts]->set_data(acc.number,acc.name,acc.sex,date,acc.address,acc.balance);
        strcpy(key_manager[this->total_accounts],acc.name);
        this->accounts.insert(pair<const char* const, Account>(key_manager[this->total_accounts],(*account_manager[this->total_accounts]))); //inserting
        this->total_accounts++;
    }
    in.close();
}

The error is:

signal SEGV (no mapping at the fault address) in realfree at 0xa2958440
0xa2958440: realfree+0x0068:    ld       [%o7 + 8], %o5

Solution

  • You allocate space for one character...

    this->key_manager[this->total_accounts] = new (nothrow) char;
    

    ...then copy many...

    strcpy(key_manager[this->total_accounts],acc.name);
    

    You should use std::string and std::vector, and avoid new and const char* in multimap keys: you'll be massively more likely to avoid bugs (including memory leaks, and especially if you have exceptions).