Problem ze zwalnianiem pamięci

0

Witam! mam napisac w MFC program, który wczytuje wektory z pliku, wykonuje na nich obliczenia, a nastepnie zapisuje wynik do pliku. Niestety problem jest taki, że dostaję błąd "out of memory" przy wczytywaniu, nie wiem, gdzie zrobiłem błąd w kodzie... pomożecie mi go znaleźć?

 

//klasa wektorów
#ifndef WEKTORY
#define WEKTORY
#include "stdafx.h"



class Vec
{
	char Naz[4];			
	int n;					
	double* A;				
	static int p;			
	static double x;		

public:
	Vec();															
	Vec(char* a, int nn, double* wspolrzedne);	
	Vec(const Vec &v);
	~Vec();									
	void Set(char* a, int nn, double* wspolrzedne);				
	void nazwa(char* nazwa);								
	void SetPrec(int precyzja);


	friend ostream & operator << (ostream &wyjscie, const Vec &vec);	
	Vec operator + (const Vec& v);										
	Vec operator - (const Vec& v);										
	Vec &operator = (const Vec& v);										
	double operator * (const Vec& v);							
};
#endif WEKTORY
 
#include "stdafx.h"
#include "Vec.h"
#include "string.h"

Vec::Vec()
{
	strcpy_s(Naz, "000");
	n = 0;
	A = new double[0];
}

Vec::Vec(char* a, int nn, double* wspolrzedne)					
{
	strcpy_s(Naz, a);
	n = nn;
	A = new double[n];
	for(int i = 0; i < n; i++) A[i] = wspolrzedne[i];
}


Vec::~Vec()													
{
	delete []A;
}

void Vec::Set(char* a, int nn, double* wspolrzedne)						
{
	strcpy_s(Naz, a);
	n = nn;
	A = new double[n];
	for(int i = 0; i < n; i++) A[i] = wspolrzedne[i];
}

int Vec::p = 3;
double Vec::x = 0;

ostream & operator<< (ostream &wyj, const Vec &vec)      
{
   wyj << vec.Naz << "[";
   wyj.precision(vec.p);
   wyj.setf(ios::fixed,ios::floatfield); 
   for(int i = 0; i < vec.n; i++)	
   wyj << " " << vec.A[i]; 
   wyj << " ]";
   return wyj;
}


Vec Vec::operator + (const Vec &v)				
{
	Vec suma;										
	int x;										
	if(n > v.n) 
	{ 
		suma.n = this->n; 
		x = v.n; 
	}		
	else 
	{ 
		suma.n = v.n; 
		x = this->n; 
	};
	suma.A = new double[suma.n];
	for(int i=0; i<suma.n; i++)				
	{
		if(i <= x) suma.A[i] = v.A[i] + this->A[i];
		else 
		{
			if(suma.n == this->n) 
				suma.A[i] = this->A[i];
			else 
				suma.A[i] = v.A[i]; 
		} 
	}
	Vec* wynik = new Vec("suma", suma.n, suma.A);
	return *wynik;
}

Vec Vec::operator - (const Vec& v)
{
	Vec roznica;										
	int x;										
	if(n > v.n) 
	{ 
		roznica.n = this->n; 
		x = v.n; 
	}		
	else 
	{ 
		roznica.n = v.n; 
		x = this->n; 
	}; 
	roznica.A = new double[roznica.n];
	for(int i=0; i<roznica.n; i++)				
	{
		if(i <= x) roznica.A[i] = A[i] - v.A[i];
		else 
		{
			if(roznica.n == this->n) 
				roznica.A[i] = A[i];
			else			  
				roznica.A[i] = -v.A[i];
		}
	}
	Vec* wynik = new Vec("roznica", roznica.n, roznica.A);
	return *wynik;
}
double Vec::operator * (const Vec& v)
{
	double wynik = 0;
	int x;									
	if(n > v.n) x = v.n; 					
	else x = this->n; 
	for(int i=0; i<x; i++)					
		wynik += A[i] * v.A[i];
	return wynik;
}

Vec::Vec(const Vec &v) : n(v.n), A(v.A?new double[n]:0)	
{ 
  strcpy_s(Naz, v.Naz);
  if(A)
	for(int i=0; i<n; i++) 
		A[i]=v.A[i];
  else
	n=0;
} 	
Vec &Vec::operator = (const Vec &v)
{
	if(&v == this) return *this;			
	delete [] A;
	n = v.n;
	A = new double[n];
	if(A)
		for(int i = 0; i < n; i++) 
			A[i] = v.A[i];
	else n = 0;
	return *this;
}

void Vec::nazwa(char *nazwa)
{
	strcpy_s(Naz, nazwa);
}

void Vec::SetPrec(int prec)
{
	p = prec;
}

	

	



//onclicked ok
void CBartosz_Sobierajski_cw_6Dlg::OnBnClickedOk()
{
	UpdateData();
	ifstream load(wejscie); 
	if(load){
		int il_wekt; 
		char Nazwa[4]; 
		int il_wspolrz;
		load >> il_wekt;		
		load.get();
		Vec* wektory = new Vec[il_wekt];
		for(int j=0; j<il_wekt; j++){
			load.getline(Nazwa, 4, ' ');							
			load >> il_wspolrz;							
			double* wspolrzedne = new double[il_wspolrz];	
			for(int i=0; i<il_wspolrz; i++){
				load >> wspolrzedne[i];	
				load.get();
			}
			wektory[j].Set(Nazwa, il_wspolrz, wspolrzedne);
		}
		wektory[0].SetPrec(prec);
		ofstream save(wyjscie);	
		save << "Dane o wektorach: " << endl; 
		for(int i = 0; i < il_wekt; i++)
		{
			save << wektory[i] << endl; 
		}
		save << endl;
		if(tryb==1){
			Vec suma;					
			for(int i=0; i<il_wekt; i++)
				suma = suma + wektory[i];
			suma.nazwa("S"); 
			save << "Suma wektorow: " << "\t\t"; 
			save << suma << endl;
		}
		if(tryb==2){
			Vec roznica = wektory[0];
			for(int i=1; i<il_wekt; i++)
			roznica = roznica - wektory[i];
			roznica.nazwa("R");					
			save << endl << "Roznica wektorow: " << "\t";
			save << roznica << endl;
		}
		if(tryb==3){
			double il_skal;
			for(int i=1; i<il_wekt; i++)
			il_skal = wektory[0] * wektory[1];
			save << endl << "Iloczyn skalarny wektorow: " << il_skal; 
		}

	}
	else {((CEdit*)GetDlgItem(IDC_EDIT1))->SetWindowText(_T("BRAK PLIKU O TEJ NAZWIE!"));}
	//OnOK();

} 
0
  1. w Vec::Set cieknie ci pamięć!
  2. przypisujesz za długi string ("roznica", "suma")) do Vec::Naz (dałeś ograniczenie do 3 znaków - pamiętaj o zerze kończącym ciąg znaków). Użyj std:string będzie bezpiecziej!
0
MarekR22 napisał(a)
  1. w Vec::Set cieknie ci pamięć!

Gdzie dokładnie cieknie mi pamięć?
Wcześniej używałem

 sum.n = this->n;

ale to chyba źle dla hermetyzacji prawda? Zwłaszcza, że ta klasa ma być bazowa dla klasy macierzy później
czy powinno być teraz

sum.n=this->nn
0

przykład:

double tab[] = {22.0, 23.4};
Vec a("a", 2, tab);
a.Set("b", 1, tab); // i tu alokuje nową pamięć a nie zwalnia starej
0

W funkcji set mam

	delete []A;
             //tu powinien byc nul ale nie wiem jak go przypisac np. A[] = NULL; ??
	strcpy_s(Naz, a);
	n = nn;
	A = new double[n];
	for(int i = 0; i < n; i++) A[i] = wspolrzedne[i];

tyle że nie umiem przypisać nulla do tego co zostało w tych komórkach - pomożecie mi to zrobic?

0

if(A) delete[] A;

0

Ok dzięki śmiga już:)

A czy tutaj:

 
Vec::~Vec()                                                                                                        
{
        delete []A;
}

nie powinno być przypisania do NULL po usunięciu obiektu? Coś tam pamiętam z wykładu, że jeśli nie będzie to poleci bania:)

Jak to zrobić? Wystarczy

 
Vec::~Vec()                                                                                                        
{
        delete []A;
        A = NULL;
}

?

0
_13th_Dragon napisał(a)

if(A) delete[] A;

Ten if jest zbędny, operatory delete z definicji podejmują akcje jedynie dla nie-NULL pointerów.

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