Knayder Temat założony przez niniejszego użytkownika |
Operatory new oraz delete. » 2016-04-18 07:27:44 Witam, czytając o wskaźnikach w książce Symfonia C++, natrafiłem na wspomniane w temacie operatory. Spodobał mi się ich sposób działania, jednak po przetestowaniu ich, nie uzyskałem satysfakcjonującego mnie wyniku. Napisałem prosty program, który nie powinien się skompilować, a jednak. Czy byłby ktoś tak miły i wytłumaczył mi, dlaczego to "działa"? #include <iostream>
using namespace std;
int main() { int * a; a = new int( 32 ); cout << "Poczatkowe a: " << * a << endl; cout << "Usuwam a" << endl; delete a; cout << "a po usunieciu: " << * a << endl; * a += 12; cout << "a po dodaniu: " << * a << endl; return 0; }
OUTPUT Poczatkowe a: 32 Usuwam a a po usunieciu: 32 a po dodaniu: 44
|
|
pekfos |
» 2016-04-18 08:35:32 To przypadek, że działa. który nie powinien się skompilować, a jednak. |
Nie ma powodów, żeby to się nie skompilowało. Kompilator nie wyłapie błędów w działaniu programu i nawet specjalnie nie próbuje. |
|
carlosmay |
» 2016-04-18 08:37:40 Fizycznie wskaźnik o nazwie 'a' nie jest usuwany, tylko zwolniona jest pamięć, na którą wskazywał. Wszystkie operacje za pośrednictwem tego wskaźnika są możliwe, jednak jest niezdefiniowane zachowanie, więc wyniki mogą być różne. Dla bezpieczeństwa należy po zwolnieniu pamięci "wyzerować" wskaźnik. a = nullptr; |
|
j23 |
» 2016-04-18 11:45:03 @carlosmay, OP nie pytał o wskaźnik, tylko o pamięć na którą ten wskaźnik wskazuje.
@Knayder, To działa, ponieważ delete nie usuwa pamięci, a jedynie ją zwalnia. Jeśli zwolniona pamięć leży na tej samej stronie pamięci co inne alokacje (w użyciu), wtedy taka pamięć będzie cały czas dostępna i nie wywoła błędu AV. W momencie, gdy zwalniana pamięć jest ostatnią używaną pamięcią na stronie, wtedy sterta może zwolnić i odmapować całą stronę, a wtedy próba dostępu spowoduje błąd AV.
|
|
michal11 |
» 2016-04-18 11:56:57 @Knayder a co właściwie twoim zdaniem powinno się zdarzyć po usunięciu *a ? |
|
carlosmay |
» 2016-04-18 12:31:36 Jeśli zwolniona pamięć leży na tej samej stronie pamięci co inne alokacje (w użyciu), wtedy taka pamięć będzie cały czas dostępna i nie wywoła błędu AV. |
Czy takie zachowanie jest standardem czy jest niezdefiniowane? |
|
Knayder Temat założony przez niniejszego użytkownika |
» 2016-04-18 12:54:00 Ja sobie wyobrażałem w taki sposób, że po wywołaniu delete na wskaźniku a, obiekt na który wskazuje, zostanie usunięty i wtedy próba wypisania tego na co wskazuje byłaby równoznaczna z czymś takim: cout << niezdefiniowana_zmienna << endl; |
|
j23 |
» 2016-04-18 14:15:40 @carlosmay, wszystko zależy od tego, jak zaimplementowana jest sterta, no i generalnie jak wygląda zarządzanie pamięcią w systemie.
@Knayder, niezdefiniowana zmienna powoduje błąd kompilacji, a my tu mówimy o sytuacji w czasie wykonania. Wywołanie delete powoduje, że pamięć zostaje zwolniona, a aplikacja nie powinna się do niej odwoływać, niezależnie od tego, czy fizycznie ona gdzieś tam jeszcze jest czy nie. Koniec, kropka. |
|
« 1 » 2 |