• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Dynamiczny przydział pamięci

0 głosów
1,330 wizyt
pytanie zadane 7 stycznia 2017 w C i C++ przez Evelek Nałogowiec (28,960 p.)
#include <iostream>
#include <cstdlib>
using namespace std;

class Klasa
{
private:
	int zmienna;
public:
	Klasa(int zmienna_ = 0) : zmienna(zmienna_) {}
	~Klasa() {}
};

int main()
{
	Klasa *wskaznik[3];
	int zmienna1;
	for (int i = 0; i < 2; i++)
	{
		cout << "Podaj liczbe: ";
		cin >> zmienna1;
		wskaznik[i] = new Klasa(zmienna1);
	}
	//usuwamy pierwszy obiekt
	delete wskaznik[0];

	cin >> zmienna1;
	wskaznik[2] = new Klasa(zmienna1);
	//okazuje sie, ze przypisalo sie do wskaznik[0] i wskaznik[2]
	system("pause");
}

Mam pytanie do tego programu. Na początku podajemy pierwszą liczbę, obiekt jest przypisywany do wskaznik[0]. Następnie podajemy kolejną liczbę, obiekt jest przypisywany do wskaznik[1]. Następnie usuwamy obiekt z miejsca wskaznik[0]. Następnie tworzymy nowy obiekt i przypisujemy do wskaznik[2]. Co się okazuje, obiekt ten został przypisany do wskaznik[0] oraz wskaznik[2]. Dlaczego tak się dzieje? Dlaczego nie przypisuje go tylko do wskaznik[2]?

3 odpowiedzi

0 głosów
odpowiedź 7 stycznia 2017 przez Michał Muzyka Pasjonat (24,080 p.)

U mnie wszystko działa bez zastrzeżeń. Dodałem:
 

  //w klasie zmienną zmieniłem na publiczną 

  for (int i = 0; i < 3; i++)
    {
        cout << "z" << wskaznik[i]->zmienna << " ";
    }

i wyświetlają się różne obiekty

komentarz 7 stycznia 2017 przez Michał Muzyka Pasjonat (24,080 p.)
obiekt jest usunięty może jest to kwestia debbugera, możesz to sprawdzić dodając np. couta w destruktorze i konstruktorze,. Może to być też kwestia kompilatora którego używasz. No właśnie z jakiego korzystasz?
komentarz 7 stycznia 2017 przez morele123 Gaduła (4,790 p.)
Robisz to na tablicy statycznej, więc co najwyżej możesz po usunięciu zawartości wskaznik[0] ustawić go na NULL.
komentarz 7 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)

Michał, zerknij na to, skopiuje ten komentarz:

Zmienne po utworzeniu dwóch obiektów i przypisaniu ich do wskaznik[0] oraz wskaznik[1].

Zmienne po usunięciu obiektu: delete wskaznik[0]

Widzimy, że zawartość wskaznik[0] została wyczyszczona i znajduje się tam obecnie syf z pamięci.

Teraz tworzymy obiekt w wskaznik[2]:

Co się okazało? wskaznik[0] oraz wskaznik[2] wskazują ten sam obszar pamięci i obiekt jest przypisywany zarówno do wskaznik[0] i wskaznik[2]. Ja chcę wiedzieć dlaczego tak się dzieje i jak zrobić, aby ten obiekt się nie przypisywał do wskaznik[0].

komentarz 7 stycznia 2017 przez Michał Muzyka Pasjonat (24,080 p.)

Wydaje mi się ze to problem twojego środowiska, bo u mnie:
Visual Studio 15

komentarz 7 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)
Visual Studio 2017 RC. Ehh.. co z tym można zrobić?
0 głosów
odpowiedź 7 stycznia 2017 przez unknown Nałogowiec (39,560 p.)
Skąd wiesz co jest w wskaznik[0] ?
komentarz 7 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)
Debuguje i podglądam wartości zmiennych.
1
komentarz 7 stycznia 2017 przez unknown Nałogowiec (39,560 p.)
Po użyciu delete na wskaźniku staje się on niepoprawny.
komentarz 7 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)
Co to znaczy "niepoprawny"? I dlaczego w tym przypadku, gdy chcę stworzyć obiekt i przypisać go do wskaznik[2], to obiekt ten jest tworzony w dwóch miejscach jednocześnie: wskaznik[0] oraz wskaznik[2]?
komentarz 7 stycznia 2017 przez unknown Nałogowiec (39,560 p.)

Niepoprawny znaczy, że juz nie wskazuje na zaalakowaną pamięć.

I dlaczego w tym przypadku, gdy chcę stworzyć obiekt i przypisać go do wskaznik[2], to obiekt ten jest tworzony w dwóch miejscach jednocześnie: wskaznik[0] oraz wskaznik[2]?

Nie jest tworzony w dwóch miejscach jednocześnie. Gdy wywołałes delete na wskaźniku to robienie z nim cokolwiek nie ma sensu. 

komentarz 7 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)

Zmienne po utworzeniu dwóch obiektów i przypisaniu ich do wskaznik[0] oraz wskaznik[1].

Zmienne po usunięciu obiektu: delete wskaznik[0]

Widzimy, że zawartość wskaznik[0] została wyczyszczona i znajduje się tam obecnie syf z pamięci.

Teraz tworzymy obiekt w wskaznik[2]:

Co się okazało? wskaznik[0] oraz wskaznik[2] wskazują ten sam obszar pamięci i obiekt jest przypisywany zarówno do wskaznik[0] i wskaznik[2]. Ja chcę wiedzieć dlaczego tak się dzieje i jak zrobić, aby ten obiekt się nie przypisywał do wskaznik[0].

komentarz 7 stycznia 2017 przez Michał Muzyka Pasjonat (24,080 p.)

Wydaje mi się że jest to po prostu problem środowiska. Ja używam Visual Studio 15

komentarz 7 stycznia 2017 przez unknown Nałogowiec (39,560 p.)
Nie wiem. Być może bug debuggera, kompilatora(a może jego optymalizacja).
0 głosów
odpowiedź 7 stycznia 2017 przez operator Stary wyjadacz (10,920 p.)
Nie możesz kasować obiektów z tablicy w ten sposób ponieważ nie zmniejszasz rozmiaru tablicy.
komentarz 7 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)
Tu własnie o to chodzi, aby nie zmniejszać wielkości tablicy.
komentarz 7 stycznia 2017 przez operator Stary wyjadacz (10,920 p.)
Nie da się bo nie. Też kiedyś miałem z tym problem. Czasami słyszę takie odpowiedzi do ćwiczeniowca i zakładam, że ma rację i ma.
komentarz 7 stycznia 2017 przez unknown Nałogowiec (39,560 p.)
A po co zmniejszać rozmiar tablicy?
komentarz 7 stycznia 2017 przez operator Stary wyjadacz (10,920 p.)
Jeśli tego nie zrobisz dostaniesz sygnał 6.
komentarz 7 stycznia 2017 przez unknown Nałogowiec (39,560 p.)
Nie, nie dostaniesz.
komentarz 7 stycznia 2017 przez operator Stary wyjadacz (10,920 p.)
Racja. Generalnie tak to wygląda w pamięci.

Bez kasowania:

0x90aea10 0x90aea20 0x90aea30

delete wskaznik[0];

0x8539a10 0x8539a20 0x8539a10

delete wskaznik[1];

0x8b6aa10 0x8b6aa20 0x8b6aa20

delete wskaznik[0];
delete wskaznik[1];

0x9c88a10 0x9c88a20 0x9c88a20
komentarz 7 stycznia 2017 przez unknown Nałogowiec (39,560 p.)
Wywoływanie delete 2 razy(lub więcej) na tym samym wskaźniku to UB
komentarz 7 stycznia 2017 przez Evelek Nałogowiec (28,960 p.)
To troszkę lipnie z tą pamięcią...

Podobne pytania

0 głosów
1 odpowiedź 574 wizyt
pytanie zadane 26 czerwca 2017 w HTML i CSS przez sapero Gaduła (4,100 p.)
0 głosów
1 odpowiedź 760 wizyt
pytanie zadane 3 września 2016 w C i C++ przez sofnir Gaduła (4,690 p.)
0 głosów
0 odpowiedzi 431 wizyt
pytanie zadane 11 czerwca 2016 w C i C++ przez L33TT12 Gaduła (3,950 p.)

93,426 zapytań

142,421 odpowiedzi

322,647 komentarzy

62,787 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

VMware Cloud PRO - przenieś swoją infrastrukturę IT do chmury
...