Przeładowanie New, Delete, problemy z pamięcią.

0

Witam! Niestety poległem na laborkach z programowania na następującym zadaniu (od prowadzącego dostajemy plik main.cpp, naszym zadaniem jest tak napisać resztę plików, aby wszystko w zgodzie i harmonii ze sobą kompilowało, pracowało, egzystowało).

//Tego pliku NIE WOLNO modyfikowac
#include "vector.hpp"
#include "vector.hpp"
#include <iostream>
const unsigned int SIZE=5;

int main()
{
  LAB::Vector v1;    // wektor elementow o zmiennym rozmiarze
  v1.push_back(3);   // dodaj na koncu wektora element o wartosci 3
  v1.push_back(-2);  // dodaj na koncu wektora element o wartosci -2
  v1.push_back(0);   // dodaj na koncu wektora element o wartosci 0
  v1.push_back(2);   // dodaj na koncu wektora element o wartosci 2
  std::cout << "v1    : "<<v1<<std::endl;
  
  const LAB::Vector * v2 =  new  const LAB::Vector(v1) ;
  std::cout << "v2    : ["<<v2->size()<<"|"<<(*v2)[0]<<","<<(*v2)[1]<<","<<(*v2)[2]<<","<<(*v2)[3]<<"]\n";

  LAB::Vector v3;
  v3=v1;
  v3[0]--;
  v3[1]++;
  v3[2]+=2;  
  v3[3]-=v3[0];  
  std::cout << "v3    : "<<v3<<std::endl;

  const LAB::Vector v4(v3);
  std::cout << "-v4   : "<< -v4 <<std::endl;
 
  std::cout << "v3+v2 : "<<v3+*v2<<std::endl;
  v3*=*v2;
  std::cout << "v3    : "<<v3<<std::endl;
  delete v2;
}

/* 
Wyjscie z programu wyglada nastepujaco:
v1    : [4|3,-2,0,2]
new Vector 
v2    : [4|3,-2,0,2]
v3    : [4|2,-1,2,0]
-v4   : [4|-2,1,-2,0]
v3+v2 : [4|5,-3,2,2]
v3    : [4|6,2,0,0]
delete Vector
*/
 

Teraz, gdy już trochę nad tym posiedziałem, nie wiem czy nie zrobiłem kodu śmietnika wartego. Mianowicie mam problem ze zwalnianiem pamięci. Próbowałem już wielu kombinacji, niestety każda na nic. oprócz main'owego delete'a, jeśli umieszcza w metodach jakiegokolwiek innego, valgrind dostaje szału i pluje mi błędami na oślep... pomocy? Gdyby się komuś chciało - dziękuję ;)

 
#ifndef _vector_hpp_
#define _vector_hpp_
	#include <iostream>
	#include <cstdlib>

namespace LAB{
	class Vector{
		public:
				
				Vector();
				Vector(const Vector&);
				~Vector();
				int size() const;
				int value(int) const;
				void push_back(int);
				static void* operator new(size_t);
				static void operator delete(void*);
				int& operator[](unsigned index) const;
				Vector operator-() const;
				Vector operator+(const Vector&) const;
				Vector& operator*=(const Vector&);
		private:
			int* element;//tablica przechowujaca kolejne wspolrzedne wektora
			unsigned ammount;//ilosc wspolrzednych
			static unsigned count;//ilosc powstalych wektorow

		};
		
	inline std::ostream& operator<<(std::ostream &strm, const Vector &K){
		strm << "[" << K.size() << "|";
		for(int i = 0; i < K.size() - 1; i ++){
			strm << K.value(i) << ",";
		}
		strm << K.value(K.size() - 1) << "]";
		return strm;
	}
}//end of nspace LAB
	
#endif // _vector_hpp_
#include "vector.hpp"
using namespace LAB;
	unsigned Vector::count = 0;
	
	Vector::Vector()//konstruktor
	{
		ammount = 0;
		element = 0;
		count++;
	}
	
	Vector::Vector(const Vector& K){//konstruktor kopiujacy
		ammount = K.ammount;
		element = new int[ammount];
		for( unsigned i = 0; i < ammount; i++)
			element[i] = K.element[i];
		count++;
	}
	
	Vector::~Vector()//destruktor
	{count--;}
		
	void Vector::push_back(int num){
		int* tmp = new int[ammount+1];
		for(unsigned i = 0; i < ammount; i++)
			tmp[i] = element[i];
		tmp[ammount] = num;
		element = tmp;
		ammount++;
	}
	
	int Vector::size() const{//zwraca liczbe elementow wektora
		return ammount;
	}
	
	int Vector::value(int i) const{//zwraca ity element wektora
		return element[i];
	}
	
	void* Vector::operator new(size_t se){
		std::cout << "new Vector" << std::endl;
		void* p = malloc(se); 
		return p;
	}
	
	void Vector::operator delete(void* vec){
		std::cout <<"delete Vector"<<std::endl;
		free(vec);
	}
	
	
	int& Vector::operator[](unsigned index) const{
		return element[index];
	}
	
	Vector Vector::operator-() const{
		Vector tmp;
		for(unsigned i = 0; i < ammount; i++)
			tmp.push_back(-element[i]);
		return tmp;
	}
	
	Vector Vector::operator+(const Vector& K) const{
		Vector tmp;
		for(unsigned i = 0; i < K.ammount; i++)
			tmp.push_back(element[i] + K.element[i]);
		return tmp;
	}
	
	Vector& Vector::operator*=(const Vector& K){
		for(unsigned i = 0; i < ammount; i++)
			element[i] = element[i]*K.element[i];	
		return *this;
	}


 
0

W C++ najczęściej nie przeładowujesz operatorów new i delete. Zarządzanie pamięcią dla pól robi się w konstruktorach i destruktorach. Poszukaj "destruktor w C++" w googlach lub książce i wykasuj te operator new i operator delete. Dodaj jeszcze operator przypisania (lub zdeklaruj w klasie jako prywatny).

Dodatkowo przy alokowaniu pamięci dynamicznie używaj new i delete (w przypadku tablic delete[]), a nie malloc i free. Na pewno nie mieszaj tych dwóch.

0

Dzięki wielkie! Co do przeładowania new i delete - musi być, a żeby prowadzący się cieszył (sprawdzenie czy umiemy z tego korzystać itp., i to w takiej właśnie postaci - free oraz malloc). Zmodyfikowałem program tak, ażeby rzeczywiście to konstruktory i destruktory zajmowały się należycie zarządzaniem pamięcią, wcześniej zrobiłem to strasznie nieudolnie.

#include "vector.hpp"
using namespace LAB;
	unsigned Vector::count = 0;
	
	Vector::Vector()//konstruktor
	{
		ammount = 0;
		element = 0;
		count++;
	}
	
	Vector::Vector(int n)//konstruktor
	{
		ammount = n;
		element = new int[n];
		count++;
	}
	
	Vector::Vector(const Vector& K){//konstruktor kopiujacy
		ammount = K.ammount;
		element = new int[ammount];
		for( unsigned i = 0; i < ammount; i++)
			element[i] = K.element[i];
		count++;
	}
	
	Vector::~Vector()//destruktor
	{
		count--;
		delete [] element;
	}
		
	void Vector::push_back(int num){
		int* tmp = new int[ammount];
		for(unsigned i = 0; i < ammount; i++)
			tmp[i] = element[i];
		delete [] element;
		element = new int[ammount+1];
		for(unsigned i = 0; i < ammount; i++)
			element[i] = tmp[i];
		element[ammount] = num;
		delete [] tmp;
		ammount++;
	}
	
	int Vector::size() const{//zwraca liczbe elementow wektora
		return ammount;
	}
	
	int Vector::value(int i) const{//zwraca ity element wektora
		return element[i];
	}	
	
	int& Vector::operator[](unsigned index) const{
		return element[index];
	}
	Vector Vector::operator-() const{
		Vector tmp(ammount);
		for(unsigned i = 0; i < ammount; i++)
			tmp.element[i] = -element[i];
		return tmp;
	}
	
	Vector Vector::operator+(const Vector& K) const{
		Vector tmp(ammount);
		for(unsigned i = 0; i < K.ammount; i++)
			tmp.element[i] = element[i] + K.element[i];
		return tmp;
	}
	Vector& Vector::operator*=(const Vector& K){
		for(unsigned i = 0; i < ammount; i++)
			element[i] = element[i]*K.element[i];	
		return *this;
	}
	
	const Vector& Vector::operator=(const Vector& K) {
		if(&K == this)
			return *this;
			
			
		delete [] element;
		
		
		element = new int[K.ammount];
		for( unsigned i = 0; i < K.ammount; i++)
			element[i] = K.element[i];
		
		ammount = K.ammount;
		
		return *this;
	}
	
	void* Vector::operator new(size_t se){
		void* tmp;
		tmp = malloc(se);
		std::cout << "new Vector" << std::endl;
		return tmp;
	}
	void Vector::operator delete(void* vec){
		std::cout << "delete Vector" << std::endl;		
		free(vec);
	}

 

Jeszcze raz dzięki, w razie W wrzucam kod.
pzdr.

1 użytkowników online, w tym zalogowanych: 0, gości: 1