Problem z przekazywaniem wsaźnika przez przeciążony operator("gubi" wartość)

0

Witam!
Mam taki problem, że podczas pisania programu do podstawowych operacji na macierzach, przeciążony operator nie zwraca mi poprawnie wskaźnika, ale może przejdźmy do kodu:

 macierz* operator + (macierz a, int b)
  {
	  for (int i =0;i<a.x;i++)
	  {
		  for (int j = 0;j<a.y;j++)
		  {
			  a.matrix[i][j]+=b;

		  }
	  }
	  macierz * temp = &a;
	  temp->drukuj();
	  return temp;
  } 

wskaźnik temp i jego metoda drukuj są po to aby sprawdzić, czy na tym etapie wszystko jest ok i tak właśnie jest, ale po wprowadzeniu w funkcji main danego ciągu instrukcji:

macierz* A = new macierz(a,b);
	macierz* C ;
	C = operator +(*A,l);
	C->drukuj(); 

nic się nie wyświetla. Zawartość tablicy matrix się nie przekazuje. o dziwo rozmiary macierzy się zgadzają (a,b) , jednak po postawieniu breakpointa odczytałem, że matrix w macierzy C:
CXX0017: Error: symbol "temp" not found
Co jest grane? Nie mam pojęcia. Pełen kod jest dostępny pod adresem:
http://pastebin.com/GtyUT20M
Proszę o jak najszybszą pomoc!

PS. Adresy w pamięci temp i C się zgadzają.

0

Ech

macierz* operator + (macierz a, int b)

pierwszym argumentem twojego operatora jest KOPIA OBIEKTU typu macierz o nazwie a. LOKALNA KOPIA, stworzona tylko i wyłącznie na potrzeby tej funkcji. Zwrócenie jej adresu poza funkcje to terroryzm. Przekaż tam wskaźnik albo referencję prznajmniej.

0

No właśnie nie mogę, operator wymaga typu klasowego, ale już chyba wiem jak to obejść.

EDIT:

Jednak nie dałem sobie rady. Zmieniłem, że zwraca nie wskaźnik, ale wartość:

 macierz operator + (macierz a, double b)
  {
	  for (int i =0;i<a.x;i++)
	  {
		  for (int j = 0;j<a.y;j++)
		  {
			  a.matrix[i][j]+=b;

		  }
	  }
	  return a; 

W mainie wpisuje:

macierz* A = new macierz(a,b);
	A->drukuj();
	macierz* C  = new macierz();
	*C = operator +(*A,l);
	C->drukuj();  

Konstruktor bezargumentowy ma na celu jedynie zarezerwowanie pamięci. Do pamięci wskazywanej przez C przekazywana jest kopia a.
Wyskakuje mi:
Access violation reading location 0xfeeefee2
Nie wiem co to za adres. Żaden z zmoich obiektów nie ma takiego.
Kurcze wskaźniki zawsze były moją piętą achillesową.

Błąd pojawia się w przeciążonym operatorze = :

 macierz& operator = (macierz a)

	{
		if (x==a.x && y==a.y){
			for (int i =0;i<x;i++)
			{
				for (int j = 0;j<y;j++)
				{
					matrix[i][j]=a.matrix[i][j];//tutaj wyrzuca wyjatek

				}
			}
		}
		else cout<<"Maciez jest za mala";
		return *this;
	}

Nie jednak się pomyliłem. Kopia matrixa się nie przekazuje do operatora =
CXX0030: Error: expression cannot be evaluated

0

Przepraszam, że post pod postem, ale chciałem,a by w temacie pojawił się nowy post i na stronie tematu było to widać. Proszę o wyrozumiałość.

Ale wracając do problemu: wydaje mi się, że matrix zz obiektu a zdąża się usunąć zanim zostanie przekazana. Jak temu zaradzić?

0

Napisałem ci w czym problem. Jeśli nie rozumiesz mojej odpowiedzi to bardzo mi przykro.

Do pamięci wskazywanej przez C przekazywana jest kopia a

Zasadniczo tak, jeśli masz dobrze napisany operator= lub/i konstruktor kopiujący... Moim zdaniem masz napisane bez sensu. Z tego co widzę z kodu to twój konstruktor bezargumentowy ani nie zeruje x i y, ani nie alokuje pamięci. A korzystasz z niego tak jakby to robił. Z reguły robi się tak że operator= zwalnia już istniejącą pamięć i alokuje od nowa, tak żeby wymiary pasowały. Poza tym zamiast przekazywać przez wartość i robić sobie masakrę -> kopia przy niszczeniu, zaraz po wyjściu z funkcji, ZWOLNI CI PAMIĘĆ i twój obiekt który byl argumentem funkcji stanie się bezużyteczny...

macierz operator + (const macierz& a, double b); //masz tu sobie stworzyć nowy obiekt i pisać do niego!
macierz& operator =(const macierz& a);
0

Zastosowałem się do Twojej rady teraz mój operator = wygląda tak:

 macierz& operator = (macierz& a)
	{
		delete matrix;
		macierz temp (a.x,a.y);
		
			for (int i =0;i<x;i++)
			{
				for (int j = 0;j<y;j++)
				{
					temp.matrix[i][j]=a.matrix[i][j];

				}
			}
			*this = temp;
			return *this;
		}

a operator +:

macierz operator + (macierz& a, int b)
{
	
	for (int i =0;i<a.x;i++)
	{
		for (int j = 0;j<a.y;j++)
		{
			a.matrix[i][j]+=b;

		}
	}
	
	return a;
} 

i teraz z przekazywaniem nie ma problemu, za to pojawił się inny: Program nie "wychodzi" mi z operatora jakby się tam zapętlił.
breakpointy ustawiłem w liniach gdzie tworzy się temp, gdzie przyrównywany jest matrix i teraz się dzieje coś bardzo dziwnego:
Po zaskoczeniu przypisywania wartości nie przechodzi mi do linijki z return ale powrotem do tworzenia temp. Co znowu skopałem?!

A tak z innej beczki Shalom nie każdy jest tak zaawansowanym programistą jak Ty. To dział newbie, powinieneś być przygotowany, że osoby tutaj dopiero zaczynają swoją przygodę z programowaniem i (tak jak ja) mogą czegoś nie ogarniać.
Wiem także, jak niewiedza innych potrafi być denerwująca, ale proszę o trochę więcej cierpliwości. Co nie zmienia faktu, że i tak jestem Ci wdzięczny za pomoc.
Pozdrawiam!

0

Ten operator= to pełny odpad, jest realizowany przez samego siebie.
Jego użycie spowoduje przepełnienie stosu.

0

Jak więc naprawić ten problem?

1

Nie wiem zbytnio dlaczego nie operujesz bezpośrednio na "this" tylko tworzysz temp. Zauważ, że robiąc

*this = temp; 

tak jak zostało to wcześniej powiedzialne wywołujesz rekurencyjnie raz jeszcze obsługę przeciążonego operatora.

0

W 99% przypadkach aby zrobić operator = trzeba połączyć destruktor z konstruktorem kopiującym.
W przypadku macierzy można spróbować nieco uprościć czyli jeżeli wymiary są takie same to nie robić delete i odpowiednio nie robić new.

0

Problem wynikał z niechcianej rekurencji w operatorze =.
Dziękuję za pomoc!

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