Wskazniki - różne komórki pamieci

0

Witam, jestem początkujacym jesli chodzi o c/c++, czy moze ktoś mi wytlumaczyć, dlaczego program w pętlach używa różnych komórek do zapisu/odczytu. Jeśli chodzi o wskaźniki rozumiałem to jako, że jesli wpisze zarezerwuje np 10 komórek poleceniem int *w = new int[10]; to będą to "stałe" zarezerwowane komórki pamieci, a np poniższego kodu komórki sie zmieniaja, (dodam, że nie zwalniam pamięci), może ktoś to ładnie wytłumaczyć dlaczego tak jest, wskazać gdzie popełniłem błąd, z góry dziękuję za odpowiedź :)


#include <iostream>

using namespace std;

int main(){

    int *w;
    w = new int[10];

    for(int i=0; i<10; i++)
    {
        cout<<(int)w<<" Wpisuje -> "<<50<<" "<<endl;
        *w=50;
        w++;
    }
    for(int i=0; i<10; i++)
    {
        cout<<(int)w<<" -> "<<*w<<" "<<endl;
        w++;
    }

    return 0;
}

1

Ponieważ w pierwszej pętli zaczynasz od 0 elementu i dobijasz do 10(a tak właściwie jako ostatni wyświetlany jest 9, ale przechodzisz ostatecznie o jeden dalej), a w drugiej pętli zaczynasz od 10 elementu, który nie istnieje. Rozwiązaniem tego jest zrobienie kopii wskaźnika.

#include <iostream>

using namespace std;

int main(){

    int *w;
    w = new int[10];
    int *x=w;
    for(int i=0; i<10; i++)
    {
        cout<<(int)w<<" Wpisuje -> "<<50<<" "<<endl;
        *w=50;
        w++;
    }
    for(int i=0; i<10; i++)
    {
        cout<<(int)x<<" -> "<<*x<<" "<<endl;
        x++;
    }

    return 0;
}

2

W drugiej pętli zaczynasz czytać pamięć z po za zakresu, bo w pierwszej pętli inkrementujesz wskaźnik, a później nie zmieniasz jego wartości, tak aby znów wskazywał na początek tablicy.

#include <iostream>
 
int main(){
 	using namespace std;
 	
 	const size_t size = 10;
 
    int *w = new int[size];
    
    for(size_t i = 0; i < size; ++i) {
    	*(w + i) = 50;
        cout<< (w + i) <<" Wpisuje -> "<< *(w + i) << " " << endl;
    }
    for(size_t i = 0; i < size; ++i) {
        cout << &w[i] <<" -> "<< w[i] << " " << endl;
    }
    
    delete[] w;
 
    return 0;
}
2

Bo zawsze idziesz „do przodu”, nigdy się nie „cofasz” — w najpierw wskazuje na pierwszy (tzn. indeksowany jako w[0]) element, potem go dziesięciokrotnie zwiększasz w pierwszej pętli, aż wskazuje na dziesiąty (w[9]). A potem, nie „cofając” go nigdzie, idziesz od tego dziesiątego i znowu zwiększasz go dziesięć razy, odwołując się już od drugiego powtórzenia do niezadeklarowanych elementów pamięci (w[10], w[11], …, w[18]).

Swoją drogą, w nowoczesnym C++ (od C++11) nie ma zbyt wielu powodów, by używać „gołego” new — w Twoim kodzie chcesz po prostu wykorzystać std::array.

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