Problem ze zwalnianiem pamięci

Odpowiedz Nowy wątek
2011-04-19 15:22

Rejestracja: 8 lat temu

Ostatnio: 8 lat temu

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();

} 
edytowany 1x, ostatnio: btus, 2011-05-05 17:04

Pozostało 580 znaków

2011-04-19 17:15

Rejestracja: 12 lat temu

Ostatnio: 16 minut temu

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!

Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 2x, ostatnio: MarekR22, 2011-04-19 17:19

Pozostało 580 znaków

2011-04-19 17:33

Rejestracja: 8 lat temu

Ostatnio: 8 lat temu

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
edytowany 1x, ostatnio: btus, 2011-04-19 17:35
jeśli A != NULL, to musisz je zwolnić - inaczej tracisz wskazania na zaalokowany obszar pamięci. - nav 2011-04-19 21:42

Pozostało 580 znaków

2011-04-19 21:41

Rejestracja: 12 lat temu

Ostatnio: 16 minut temu

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

Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.

Pozostało 580 znaków

2011-05-05 16:47

Rejestracja: 8 lat temu

Ostatnio: 8 lat temu

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?

edytowany 1x, ostatnio: btus, 2011-05-05 16:51

Pozostało 580 znaków

2011-05-05 17:17

Rejestracja: 14 lat temu

Ostatnio: 2 dni temu

0

if(A) delete[] A;


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2011-05-05 17:25

Rejestracja: 8 lat temu

Ostatnio: 8 lat temu

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;
}

?

Pozostało 580 znaków

NULL
2011-05-05 17:38
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.

Pozostało 580 znaków

Odpowiedz

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