I have a strange, at least for me, issue with dynamic allocation of char array in constructor.
I have couple of constructors and functions in my class which perform dynamic allocation of char array and only one of them throws "corrupted top size" exception from malloc(); Code is provided below and i have left the comment where exception is thrown. The pointers are simply defined in class definition as "char *_name". All other constructors and functions are checked and are working properly. Any help will be appreciated.
#include "contact.h"
#include <stdexcept>
#include <iostream>
MT::Contact::Contact() :
_name_length(0),
_surname_length(0),
_birth_date_length(0),
_phone_number_length(0),
_city_length(0),
_position_length(0),
_size(0),
_name(nullptr),
_surname(nullptr),
_birth_date(nullptr),
_phone_number(nullptr),
_city(nullptr),
_position(nullptr),
_to_file(nullptr),
_new_contact(true),
_modified_contact(false)
{
}
MT::Contact::Contact(int8_t *data) :
_to_file(nullptr)
{
int start = 0;
_name_length = *(data+start);
++start;
_surname_length = *(data+start);
++start;
_birth_date_length = *(data+start);
++start;
_phone_number_length = *(data+start);
++start;
_city_length = *(data+start);
++start;
_position_length = *(data+start);
++start;
_name = new char[_name_length];//Here is the exception (and for all other allocations in this constructor)
strncpy(_name, reinterpret_cast<char *>(data+start), _name_length);
start += _name_length;
_surname = new char[_surname_length];
strncpy(_surname, reinterpret_cast<char *>(data+start), _surname_length);
start += _surname_length;
_birth_date = new char[_birth_date_length];
strncpy(_birth_date, reinterpret_cast<char *>(data+start), _birth_date_length);
start += _birth_date_length;
_phone_number = new char[_phone_number_length];
strncpy(_phone_number, reinterpret_cast<char *>(data+start), _phone_number_length);
start += _phone_number_length;
_city = new char[_city_length];
strncpy(_city, reinterpret_cast<char *>(data+start), _city_length);
start += _city_length;
_position = new char[_position_length];
strncpy(_position, reinterpret_cast<char *>(data+start), _position_length);
_new_contact = false;
_modified_contact = false;
}
MT::Contact::Contact(const MT::Contact &other) :
_name_length(other._name_length),
_surname_length(other._surname_length),
_birth_date_length(other._birth_date_length),
_phone_number_length(other._phone_number_length),
_city_length(other._city_length),
_position_length(other._position_length),
_size(other._size),
_to_file(nullptr),
_new_contact(other._new_contact), _modified_contact(other._modified_contact)
{
_name = new char[_name_length];
strcpy(_name, other._name);
_surname = new char[_surname_length];
strcpy(_surname, other._surname);
_birth_date = new char[_birth_date_length];
strcpy(_birth_date, other._birth_date);
_phone_number = new char[_phone_number_length];
strcpy(_phone_number, other._phone_number);
_city = new char[_city_length];
strcpy(_city, other._city);
_position = new char[_position_length];
strcpy(_position, other._position);
}
MT::Contact::Contact(MT::Contact &&other):
_name_length(other._name_length),
_surname_length(other._surname_length),
_birth_date_length(other._birth_date_length),
_phone_number_length(other._phone_number_length),
_city_length(other._city_length),
_position_length(other._position_length),
_size(other._size),
_to_file(nullptr),
_new_contact(other._new_contact), _modified_contact(other._modified_contact)
{
_name = other._name;
_surname = other._surname;
_birth_date = other._birth_date;
_phone_number = other._phone_number;
_city = other._city;
_position = other._position;
other._size = 0;
other._name_length = 0;
other._birth_date_length = 0;
other._phone_number_length = 0;
other._surname_length = 0;
other._city_length = 0;
other._position_length = 0;
other._name = nullptr;
other._surname = nullptr;
other._birth_date = nullptr;
other._phone_number = nullptr;
other._city = nullptr;
other._position = nullptr;
other._to_file = nullptr;
}
MT::Contact &MT::Contact::operator=(const MT::Contact &other)
{
if (this != &other){
if (_name != nullptr){
delete [] _name;
}
if (_surname != nullptr){
delete [] _surname;
}
if (_birth_date != nullptr){
delete [] _birth_date;
}
if (_phone_number != nullptr){
delete [] _phone_number;
}
if (_city != nullptr){
delete [] _city;
}
if (_position != nullptr){
delete [] _position;
}
_name_length = other._name_length;
_surname_length = other._surname_length;
_birth_date_length = other._birth_date_length;
_phone_number_length = other._phone_number_length;
_city_length = other._city_length;
_position_length = other._position_length;
_size = other._size;
_name = new char[_name_length];
strcpy(_name, other._name);
_surname = new char[_surname_length];
strcpy(_surname, other._surname);
_birth_date = new char[_birth_date_length];
strcpy(_birth_date, other._birth_date);
_phone_number = new char[_phone_number_length];
strcpy(_phone_number, other._phone_number);
_city = new char[_city_length];
strcpy(_city, other._city);
_position = new char[_position_length];
strcpy(_position, other._position);
_new_contact = other._new_contact;
_modified_contact = other._modified_contact;
}
return *this;
}
MT::Contact &MT::Contact::operator=(MT::Contact &&other)
{
if (this != &other){
if (_name != nullptr){
delete [] _name;
}
if (_surname != nullptr){
delete [] _surname;
}
if (_birth_date != nullptr){
delete [] _birth_date;
}
if (_phone_number != nullptr){
delete [] _phone_number;
}
if (_city != nullptr){
delete [] _city;
}
if (_position != nullptr){
delete [] _position;
}
_name_length = other._name_length;
_surname_length = other._surname_length;
_birth_date_length = other._birth_date_length;
_phone_number_length = other._phone_number_length;
_city_length = other._city_length;
_position_length = other._position_length;
_size = other._size;
_name = other._name;
_surname = other._surname;
_birth_date = other._birth_date;
_phone_number = other._phone_number;
_city = other._city;
_position = other._position;
_new_contact = other._new_contact;
_modified_contact = other._modified_contact;
other._size = 0;
other._name_length = 0;
other._surname_length = 0;
other._city_length = 0;
other._position_length = 0;
other._name = nullptr;
other._surname = nullptr;
other._birth_date = nullptr;
other._phone_number = nullptr;
other._city = nullptr;
other._position = nullptr;
other._to_file = nullptr;
std::cout << "Move" << std::endl;
}
return *this;
}
void MT::Contact::set_name(const char *name)
{
if (name == nullptr || strcmp(name, "") == 0){
throw std::invalid_argument("void MT::Contact::set_name(const char *name): empty [name] was provided");
}
_name_length = strlen(name);
if (!_new_contact){
delete [] _name;
_modified_contact = true;
}
_name = new char[_name_length];
strcpy(_name, name);
_size += _name_length;
}
void MT::Contact::set_surname(const char *surname)
{
if (surname != nullptr && strcmp(surname, "") != 0){
_surname_length = strlen(surname);
if (!_new_contact){
delete [] _surname;
_modified_contact = true;
}
_surname = new char[_surname_length];
strcpy(_surname, surname);
_size += _surname_length;
}
}
void MT::Contact::set_birthdate(const char *birth_date)
{
if (birth_date != nullptr && strcmp(birth_date, "") != 0){
_birth_date_length = strlen(birth_date);
if (!_new_contact){
delete [] _birth_date;
_modified_contact = true;
}
_birth_date = new char[_birth_date_length];
strcpy(_birth_date, birth_date);
_size += _birth_date_length;
}
}
void MT::Contact::set_phone_number(const char *phone_number)
{
if (phone_number != nullptr && strcmp(phone_number, "") != 0){
_phone_number_length = strlen(phone_number);
if (!_new_contact){
delete [] _phone_number;
_modified_contact = true;
}
_phone_number = new char[_phone_number_length];
strcpy(_phone_number, phone_number);
_size += _phone_number_length;
}
}
void MT::Contact::set_city(const char *city)
{
if (city != nullptr && strcmp(city, "") != 0){
_city_length = strlen(city);
if (!_new_contact){
delete [] _city;
_modified_contact = true;
}
_city = new char[_city_length];
strcpy(_city, city);
_size += _city_length;
}
}
void MT::Contact::set_position(const char *position)
{
if (position != nullptr && strcmp(position, "") != 0){
_position_length = strlen(position);
if (!_new_contact){
delete [] _position;
_modified_contact = true;
}
_position = new char[_position_length];
strcpy(_position, position);
_size += _position_length;
}
}
int MT::Contact::size() const
{
return _size;
}
const char *MT::Contact::name() const
{
return _name;
}
const char *MT::Contact::surname() const
{
if (_surname == nullptr){
return "";
}
return _surname;
}
const char *MT::Contact::birth_date() const
{
if (_birth_date == nullptr){
return "";
}
return _birth_date;
}
const char *MT::Contact::phone_number() const
{
if (_phone_number == nullptr){
return "";
}
return _phone_number;
}
const char *MT::Contact::city() const
{
if (_city == nullptr){
return "";
}
return _city;
}
const char *MT::Contact::position() const
{
if (_position == nullptr){
return "";
}
return _position;
}
bool MT::Contact::is_new() const
{
return _new_contact;
}
bool MT::Contact::is_modified() const
{
return _modified_contact;
}
int8_t *MT::Contact::to_file()
{
if (_to_file != nullptr){
delete [] _to_file;
}
_to_file = new int8_t[_size];
_to_file[0] = static_cast<int8_t>(_size);
_to_file[1] = static_cast<int8_t>(_size >> 8);
_to_file[2] = _name_length;
_to_file[3] = _surname_length;
_to_file[4] = _birth_date_length;
_to_file[5] = _phone_number_length;
_to_file[6] = _city_length;
_to_file[7] = _position_length;
int start = 8;
memcpy(_to_file+start, _name, _name_length);
start += _name_length;
memcpy(_to_file+start, _surname, _surname_length);
start += _surname_length;
memcpy(_to_file+start, _birth_date, _birth_date_length);
start += _birth_date_length;
memcpy(_to_file+start, _phone_number, _phone_number_length);
start += _phone_number_length;
memcpy(_to_file+start, _city, _city_length);
start += _city_length;
memcpy(_to_file+start, _position, _position_length);
return _to_file;
}
MT::Contact::~Contact()
{
if (_name != nullptr){
delete [] _name;
}
if (_surname != nullptr){
delete [] _surname;
}
if (_birth_date != nullptr){
delete [] _birth_date;
}
if (_phone_number != nullptr){
delete [] _phone_number;
}
if (_city != nullptr){
delete [] _city;
}
if (_position != nullptr){
delete [] _position;
}
if (_to_file != nullptr){
delete [] _to_file;
}
}
...
Aucun commentaire:
Enregistrer un commentaire