Resizing and operator= overloading - c++

I've implemented a class named LipidType but the program crashes when the resize function and assignment operator overloading are called but I can't find out the error in the code. These are the private members of the class
private:
std::string *mod;
std::string *classe;
int matches;
double mz;
double *intensity;
double *frag;
std::string name;
int maxsize;
int length;
and these are the functions
LipidType& LipidType::operator=(const LipidType& otherlip) //assignment operator
{
if (this == &otherlip) return *this; // handle self assignment
if(otherlip.maxsize > maxsize)
{
std::cout << "Resizing" << std::endl;
resize(otherlip.maxsize);
}
for(int i=0; i<otherlip.length; i++)
{
mod[i]=otherlip.mod[i];
classe[i]=otherlip.classe[i];
intensity[i]=otherlip.intensity[i];
frag[i]=otherlip.frag[i];
}
matches=otherlip.matches;
name=otherlip.name;
mz=otherlip.mz;
length = otherlip.length;
return *this;
}
void LipidType::resize(int nusize)
{
maxsize = nusize;
std::string* temp1=new std::string[maxsize];
std::string* temp2=new std::string[maxsize];
double* temp3=new double[maxsize];
double* temp4=new double[maxsize];
for(int i=0; i<length; i++)
{
temp1[i]=mod[i];
temp2[i]=classe[i];
temp3[i]=intensity[i];
temp4[i]=frag[i];
}
delete [] mod;
delete [] classe;
delete [] intensity;
delete [] frag;
mod=temp1;
classe=temp2;
intensity=temp3;
frag=temp4;
}

Related

a user defined class of ARRAY in c++ with pointer

This code is a class of arrays definition that uses dynamic memory to allocate memory. The command ArrayClass temp(_size); in operator+ method gives the following runtime error.
Unhandled exception at 0x7715C54F in ArrayClass.exe: Microsoft C++
exception: std::bad_array_new_length at memory location 0x0033FB10.
If we convert this command to ArrayClass *temp = new ArrayClass(_size), no error will be occured. But the new object temp that was allocated by new operator will not be deleted.
Does anyone have a solution?
#include <iostream>
using namespace std;
class ArrayClass {
private:
int _size;
float* _ar;
public:
ArrayClass(const int& size) {
_size = size;
_ar = new float[_size];
}
~ArrayClass() {
delete[]_ar;
}
const ArrayClass& operator=(const ArrayClass& RightOperand) {
if (this != &RightOperand) {
if (this->_size != RightOperand._size) {
delete[] this->_ar;
this->_size = RightOperand._size;
this->_ar = new float[this->_size];
}
for (int i = 0; i < RightOperand._size; i++)
{
this->_ar[i] = RightOperand._ar[i];
}
}
return *this;
}
const ArrayClass& operator+(const ArrayClass& RightOperand) {
//*this+RightOperand
if (this->_size != RightOperand._size) {
cout << "different Size";
exit(1);
}
ArrayClass temp(_size);
for (int i = 0; i < _size; i++)
{
temp._ar[i] = this->_ar[i] + RightOperand._ar[i];
}
return temp;
}
};
int main() {
ArrayClass x(5), y(5), z(5);
x = y;
z= x + y;
return 0;
}

Initializing parent class' pointer using initializer list

I have a class strings:
class strings
{
protected:
string *ptr;
int size;
public:
strings() {
ptr = NULL;
size = -1;
}
strings(int size) {
this->size = size;
ptr = new string[size];
}
string* retPtr() {
return ptr;
}
void setPtr(int size)
{
ptr = new string[size];
this->size = size;
}
strings(const strings& obj) {
this->size = obj.size;
for (int i = 0;i < size;++i)
this->ptr[i] = obj.ptr[i];
}
friend istream& operator>>(istream& input, strings& obj) {
cin.ignore();
cout << "Enter " << obj.size << " string one by one:\n";
for (int i = 0;i < obj.size;++i)
{
getline(input, obj.ptr[i]);
}
return input;
}
friend ostream& operator<<(ostream& output, const strings& obj) {
cout << "Strings are:\n";
for (int i = 0;i < obj.size;++i)
output << obj.ptr[i] << "\n";
return output;
}
void operator =(const strings& obj)
{
this->size = obj.size;
for (int i = 0;i < size;++i)
ptr[i] = obj.ptr[i];
}
~strings()
{
delete[]ptr;
}
};
Another class stringsFromNumbers:
class stringsFromNumbers:public strings
{
int numbers;
public:
stringsFromNumbers(){
numbers = -1;
}
stringsFromNumbers(int size, int numbers):strings(size){
this->numbers = numbers;
}
stringsFromNumbers(const stringsFromNumbers& obj)
{
this->numbers = obj.numbers;
this->size = obj.size;
for (int i = 0;i < size;++i)
this->ptr[i] = obj.ptr[i];
}
friend istream& operator>>(istream& input, stringsFromNumbers& obj) {
cin.ignore();
cout << "Enter " << obj.size << " string one by one:\n";
for (int i = 0;i < obj.size;++i)
{
getline(cin, obj.ptr[i]);
}
return input;
}
friend ostream& operator<<(ostream& output, const stringsFromNumbers& obj) {
cout << "Numbers are: " << obj.numbers;
cout << "\nStrings are:\n";
for (int i = 0;i < obj.size;++i)
output << obj.ptr[i] << "\n";
return output;
}
void operator =(const stringsFromNumbers& obj)
{
this->numbers = obj.numbers;
this->size = obj.size;
for (int i = 0;i < size;++i)
this->ptr[i] = obj.ptr[i];
}
~stringsFromNumbers()
{
delete[] ptr;
}
};
Whenever i try execute this line of code:
stringsFromNumbers obj2(N, P);
where N and P are valid integers, I get an "Access Reading Violation", do you see something wrong in the code?
I have been stuck on this for almost 2 hours. I have tried debugging and fixing it, i have also tried multiple other methods. The exception takes me to this function:
inline void _Container_base12::_Orphan_all() noexcept {
#if _ITERATOR_DEBUG_LEVEL == 2
if (_Myproxy) { // proxy allocated, drain it
_Lockit _Lock(_LOCK_DEBUG);
for (auto _Pnext = &_Myproxy->_Myfirstiter; *_Pnext; *_Pnext = (*_Pnext)->_Mynextiter) {
(*_Pnext)->_Myproxy = nullptr;
}
_Myproxy->_Myfirstiter = nullptr;
}
#endif // _ITERATOR_DEBUG_LEVEL == 2
}
The problem is with this function most probably but how can it be fixed?
stringsFromNumbers(int size, int numbers):strings(size){
this->numbers = numbers;
}
Both stringsFromNumbers::~stringsFromNumbers and strings::strings call delete[] on ptr, so the array is attempted to be freed twice; the second time causes an issue.
Only one of these classes should be responsible for managing the lifecycle of ptr. Remove the delete[] from stringsFromNumbers::~stringsFromNumbers.
If in some other case you've got a valid reason to free the array in the destructor of a subclass, make sure the parent class destructor is able to deal with the new state (e.g. by setting ptr to nullptr after deleting it), but in general you should avoid the complexity of making both classes sharing responsibility for freeing the memory.

How to convert template T to a class pointer

I am trying to implement a template Array class that can hold pointers as well as primitive data types.
But when calling the destructor, the pointers in that array are not properly deleting.
So I am trying to convert each item in that array to its corresponding class and call delete. But I met with an issue. I'm not able to convert T type to my class pointer.
My intention is to delete items in that array. Can someone please help in this?
template <class T>
class LIBRARY_EXPORT MyArrayT
{
public:
MyArrayT()
{
this->count = 0;
}
~MyArrayT()
{
if ((this->count) > 0)
{
//std::cout << "Deleting Array values" << std::endl;
delete[] this->values;
//free(this->values);
/*for (int i = 0; i < this->count; i++)
{
delete this->values[i];
}*/
this->count = 0;
}
}
void SetValue(std::vector< T > items)
{
//Delete existing memory
delete[] this->values;
this->count = items.size();
if (this->count > 0)
{
this->values = new T[this->count];
for (int i = 0; i < count; i++)
{
this->values[i] = items[i];
}
}
}
void SetValue(T items, int index)
{
if (this->count > index)
{
this->values[index] = items;
}
}
T GetValue(int index)
{
if (this->count > index)
{
return this->values[index];
}
return NULL;
}
T* GetValue()
{
return this->values;
}
_int64 GetCount()
{
return this->count;
}
private:
_int64 count;
T* values;
};
class LIBRARY_EXPORT MyString
{
public:
MyString();
~MyString();
void SetValue(std::string str);
std::string GetValue();
_int64 GetCount();
private:
_int64 count;
char* value;
};
int main()
{
MyArrayT<MyString*>* MyArrayValue = new MyArrayT<MyString*>() ;
vector<MyString*> value9;
MyString* opt1 = new MyString();
opt1->SetValue("Option: 1");
value9.push_back(opt1);
MyArrayValue->SetValue(value9);
MyArrayT<int>* MyArrayValueInt = new MyArrayT<int>() ;
vector<int> value1;
value1.push_back(1);
value1.push_back(2);
MyArrayValueInt->SetValue(value1);
delete MyArrayValue; //Calling this delete doesn't calling the ~MyString() destructor
delete MyArrayValueInt;
}

Using binary operator "--" for vector

I have my own Class Vector and I'd like to create an operator-- to delete last element in array. But in my implementation i got an error:
binary "--": Vector does not define this operator or a conversion to a
type acceptable to the predefined operator.
How do i declare it correctly?
class Vector {
private:
int *vect;
int size;
public:
void operator--();
}
void Vector::operator--() {
int *tmp = vect;
size--;
vect = new int(size);
for (int i = 0; i < size; i++) vect[i] = tmp[i];
delete[] tmp;
}
I should have declared it like this:
void operator--(int);
And implemented like this:
void Vector::operator--(int) {
if (size>1) size--;
else std::cout << "Only one element in vector.\n";
}
this (int) helps the compiler to differ prefix and postfix increments or decrements.
An example:
struct A {
void operator --(int) { std::cout << "Postfix\n"; }
void operator --() { std::cout << "Prefix\n"; }
};
int main()
{
A a;
a--;
--a;
}
Thanks to #PaulMcKenzie for the link.

Overloading addition operator (adding a string to an object using a function)

I'm creating a dynamic array class and I'm new to c++. I'm having trouble overloading the addition operator to add a string to an object. When I do try to add a string, nothing shows up on the compile screen. I also added my copy constructor, destructor, overloaded assignment operator, and overloaded ostream operator just in case any of those were the issue. Thank you so much for the help!!
DynamicStringArray::~DynamicStringArray()
{
delete[] dynamic_Array;
dynamic_Array = NULL;
}
DynamicStringArray::DynamicStringArray(const DynamicStringArray& first)
{
size = first.returns_Size();
dynamic_Array = new string[size];
for (int n = 0; n < size; n++)
{
dynamic_Array[n] = first.get_Entry(n);
}
}
void DynamicStringArray::operator =(const DynamicStringArray& first)
{
this->size = first.returns_Size();
this->dynamic_Array = new string[size];
for (int i = 0; i < this->size; i++)
{
this->dynamic_Array[i] = first.get_Entry(i);
}
}
ostream& operator <<(ostream& out, const DynamicStringArray& first) //nonmember requires 2 arguments
{
for (int i = 0; i < first.size; i++)
{
out << first.dynamic_Array[i] << endl;
}
return out;
}
void DynamicStringArray::add_Entry(string a)
{
string* Temp_Array = dynamic_Array; //old array
dynamic_Array = new string[size + 1]; //new array
for (int i= 0; i < size; i++) //copy old string values to temp array
{
dynamic_Array[i] = Temp_Array[i];
}
dynamic_Array[size] = a; //puts string a into last position of new array
delete[]Temp_Array; //free memory space
size++;
}
DynamicStringArray DynamicStringArray::operator +(const string& a)
{
DynamicStringArray added;
added.add_Entry(a);
return added;
}
int main()
{
DynamicStringArray fav_Foods;
fav_Foods.add_Entry("pasta");
fav_Foods.add_Entry("sushi");
fav_Foods + "Burgers";
cout << fav_Foods << endl;
}
DynamicStringArray DynamicStringArray::operator +(const string& a)
{
DynamicStringArray added;
added.add_Entry(a);
return added;
}
Why do you think you need to create a new DynamicStringArray added?
Simply call add_Entry(a) on the current instance. Also, operator+() should return a reference to the instance it is called upon:
DynamicStringArray& DynamicStringArray::operator+(string const &a)
{
add_Entry(a);
return *this;
}