Problem z wyobrażeniem sobie działania "new"

0

No to tak, program mi działa i wszystko jest git, ale choć wszystko działa, to jakoś nie nadążam za przeznaczeniem "new". W książce jak wół jest napisane, że służy on do alokowania miejsca w pamięci dla obiektu. Jakoś jednak nie mogę sobie tego w głowie poukładać.

No mam np.
float *pa= new float;

I o co teraz chodzi? Co to jest sterta już wiem,bo przeczytałem w c++ dla każdego. Co takiego jednak daje mi ten operator "new"? Chodzi o to, że strasznie mi się kiełbasi jego znaczenie z sensem definicji samego wskaźnika. No jest sobie jakiś adres. Pod tym adresem coś się znajduje i dostęp do tego uzyskuje się przy pomocy wyłuskania. No, to już wiem i rozumiem. No to skoro mam adres i skoro mam wskaźnik (worek), do którego mogę ten adres włożyć, to po co jeszcze mi "new"?

Czy tu chodzi o to, że przy pomocy "new" zwyczajnie wyznaczam miejsce w stercie dla...? no właśnie dla czego...? dla adresu nie. No to rozumiem, że raczej dla obiektu. No właśnie, proszę o wytłumaczenie,bo widzę, że samo poprawne napisanie z głowy kodu to nie wszystko. Jak widać, trzeba jeszcze rozumieć to, co się samemu wymyśliło;-))

0

Sam wskaźnik niczego nie daje. On pokazuje gdzieś. Żeby to gdzieś miało sens ten obszar musi być zarezerwowany przez Twój program.

float *ptr;

Gdzie teraz pokazuje ptr? Zazwyczaj będzie to jakieś "losowe" miejsce. Dostęp do niego, czyli: *ptr, skończy się najpewniej błędem.

float *ptr = new float;

Operator new alokuje miejsce na stercie na Twoją zmienną i zwraca wskaźnik do tego miejsca - teraz wskaźnik wskazuje na to, na co powinien.

Poza samym alokowaniem pamięci, bardzo ważną funkcją operatora new jest wywoływanie konstruktora.

0

Sory, czytam jeszcze i analizuje to co mi napisałeś.

To po kolei:

Rozumiem, że w kodzie niżej wskaźnik *pa przechowuje (wskazuje) adres w pamięci, pod którym znajduje się zmienna a. Tylko, że bez użycia operatora "new" ten adres jest całkowicie losowy...
[code]
float a;
float *pa=&a;
[/code]

Nie no, mózg mi się chyba zatrzymał. Przecież to są proste rzeczy!Kurde!
A gdy dorzucę "new" ...no właśnie...co oznacza samo new float?
Myślałem, że sens tego kodu wyżej jest taki, że wskaźnik *pa już na coś konkretnego wskazuje, na adres pod którym znajduje się zmienna a...
No to skoro już wskazuje ten adres,to po czorta jeszcze "new"??

0

float *ptr = new float;

Tworzymy zmienną wskaźnikową *ptr, która może mieć albo wartość 0, albo jakieś śmieci. Następnie wywołujemy operator new, który alokuje pamięć, tworzy tam obiekt typu float i zwraca jego położenie w pamięci.

prościej się chyba już nie da

0
finito napisał(a):

[code]
float a;
float *pa=&a;
[/code]

Nie no, mózg mi się chyba zatrzymał. Przecież to są proste rzeczy!Kurde!
A gdy dorzucę "new" ...no właśnie...co oznacza samo new float?
Myślałem, że sens tego kodu wyżej jest taki, że wskaźnik *pa już na coś konkretnego wskazuje, na adres pod którym znajduje się zmienna a...
No to skoro już wskazuje ten adres,to po czorta jeszcze "new"??

W typ wypadku nie potrzebujesz żadnego new. Zmienna a znajduje się na stosie a w pa jest jej adres, wszystko jest ok. new alokuje pamięć na stercie, nie na stosie. Musisz użyć tego operatora, jeżeli potrzebujesz dynamicznej alokacji pamięci.

new float oznacza "zaalokuj pamięć na dane typu float w ilości jeden float". Po alokacji operator zwraca wskaźnik do tego zaalokowanego obszaru. Wskaźnik ten jest niezbędny żeby mieć do niego dostęp - jeżeli stracisz ten wskaźnik stracisz dostęp, ale miejsce pozostanie zaalokowane.

0

Tworzysz wskaźnik. Tworzy sie on na stosie, jest zwykłym obiektem, który automatycznie zostanie usunięty podczas wyjścia z bloku, w którym został utworzony, czyli jak program wyjdzie poza zasięg zmiennej.
Jak każdy taki obiekt, skoro go nie wyzerowaliśmy, a już zajął sobie jakieś miejsce w pamięci (w tym przypadku na stosie), to przyjął to, co tam się wcześniej znajdywało. Wskaźnik to coś interpretuje jako adres, ale my tego nie chcemy, bo są to jakieś śmieci, które jakis program kiedys stworzyl, uzywal i potem zwolnił to miejsce w pamięci.

Czyli stworzyliśmy normalny wskaźnik, ale nie nadaliśmy mu adresu. Jakiś adres ma, w zasadzie jakąś wartość, która byłą w tym miejscu w pamięci.

Operator new alokuje nam pamięć na stercie, zwraca adres tego miejsca. Ilość miejsca alokowanego jest oczywiście zależna od typu zmiennej, jaką podaliśmy operatorowi. Problem w tym, że nie możemy odwołać siędo tego miejsca nazwą zmiennej, tak jak to robiliśmy tworząc zmienne na stosie. Ale skoro operator zwraca nam adres tego miejsca, to przypisujemy ten adres do wskaźnika (który pozwala na wskazywanie na zmienne odpowiedniego typu). Od tej chwili ten adres przypisany do naszego wskaźnika jest jedynym łącznikiem z tym naszym miejscem w pamięci (na stercie). Jeżeli wyjdziemy poza blok, w którym utworzyliśmy wskaźnik to sięon automatycznie usunie i stracimy na zawsze kontakt z naszym obiektem na stercie. Jeżeli wcześniej nie oddamy (operatorem delete) tego miejsca w pamięci to wciąż nasz program ma to miejsce zarezerwowane, czyli pojawia się problem.

Edit: Jak zacząłem pisać to nie było kilku postów wyżej :D

0
Sopelek napisał(a):

float *ptr = new float;

Tworzymy zmienną wskaźnikową *ptr, która może mieć albo wartość 0, albo jakieś śmieci. Następnie wywołujemy operator new, który alokuje pamięć, tworzy tam obiekt typu float i zwraca jego położenie w pamięci.

prościej się chyba już nie da

No dobra, a skąd pewność (jeśli cie dobrze zrozumiałem), że po napisaniu:
float *ptr = new float;
nasz wskaźnik *ptr będzie miał adres ten konkretny, który chcemy. Czekaj,bo mam wrażenie, że chyba gdzieś mi uciekło znaczenie pojęcia "adres";-))

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