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

Problem ze wskaznikami

Object Storage Arubacloud
0 głosów
320 wizyt
pytanie zadane 15 listopada 2015 w C i C++ przez Baakoma Użytkownik (780 p.)

Witam, chciałem spróbować napisać program, który najpierw utworzy dynamiczną tablicę, potem ją usunie, utworzy nową, a w funkcji dodaj() przekaze nową tablicę i ją zwiększy o 1. Niestety mam problem, program wywala losowo w różnych miejscach i nie działa tak jak powinien ;/ Od wczoraj w nocy bawię się i nie potrafię znaleźć problemu ;/ Prosiłbym o wytłumaczenie co robię nie tak, z góry dziękuję.Tutaj kod:

#include <iostream>


using namespace std;

void dodaj(int *t, int w, int l);

int main()
{
    int * tab = new int[10];
    for (int i = 0; i < 10; i++)
    {
        *tab = i;
        cout << "Adres pierwszej tablicy: " << (int)tab << endl;
        cout << "Wartosc pierwszej tablicy: " << *tab << endl;
        tab++;
    }
    cout << endl << "Tworzenie drugiej tablicy" << endl << endl;
    delete [] tab;

    tab = new int[11];
    for (int i = 0; i < 11; i++)
    {
        *tab = i*i;
        cout << "Adres drugiej tablicy: " << (int)tab << endl;
        cout << "Wartosc drugiej tablicy: " << *tab << endl;
        tab++;
    }
    cout << endl << "Powiekszanie tablicy" << endl << endl;
    dodaj(tab,11,666);

    delete [] tab;
    return 0;
}

void dodaj(int *tab, int wielkosc, int liczba)
{
    int * newTab = new int[wielkosc+1];
    for (int i = 0; i < wielkosc; i++)
    {
        newTab[i] = tab[i];
        cout << "Adres talibcy dla newTab: " << (int) newTab++ << endl << endl;
        cout << "Wartosc talibcy dla newTab: " << *newTab << endl;
        cout << endl;
        cout << "Adres tablicy dla tab: " << (int)tab << endl << endl;
        cout << "Wartosc talibcy dla Tab: " << *tab << endl;
        tab++;
    }
    newTab[wielkosc] = liczba;
    if(tab) delete [] tab;
    cout << "Obecny adres newTab: " << (int)newTab << endl;
    tab = newTab;
    cout << endl;
    cout << "Adres tablicy dla tab po zmianie: " << (int)tab++ << endl << endl;
    cout << "Wartosc talibcy dla Tab po zmianie: " << *tab << endl;
}

 

1 odpowiedź

0 głosów
odpowiedź 15 listopada 2015 przez Krawiec91 Pasjonat (19,600 p.)

Przyczyną problemów jest wskaźnik tab, a mianowicie:
1. W pierwszej petli for, w każdym przejściu pętli inkrementujesz ten wskaźnik. Następnie próbujesz zwolnić pamięć. Problem w tym, że zwalniasz nie tą pamięć, której żądałeś za pomocą operatora new. Wskaźnik tab przed pętlą, ma inną wartość, niż po wykonaniu pętli.
2. W drugie pętli for podobna sytuacja związana z inkrementacją wskaźnika. Z tą różnicą, że po wykonaniu pętli do funkcji dodaj() nie przekazujesz tablicy, którą zaalokowałeś wcześniej, tylko zawartość pamięci znajdującą się bezpośrednio za tablicą.

A żeby tego uniknąć, to możesz sobie zadeklarować pomocniczy wskaźnik na typ, do którego przypiszesz adres tablicy i będzie mógł z użyciem tego wskaźnika przesuwać się po kolejnych polach tablicy. Zawsze też będziesz mógł się odwołać do oryginalnego wskaźnika (nazwa tablicy). Inną opcją jest, użycie notacji ze wskaźnikiem:
 

for (int i=0;i<10;i++)
{
  *(tab+i)=i;
  cout<<"Adres pierwszej tablicy: "<<(int)(tab+i)<<endl;
  cout<<"Wartosc pierwszej tablicy: "<<*(tab+i)<<endl;
}

Adres jaki przechowuje wskaźnik jest nieruszony, dostęp do kolejnych elementów jest możliwy dzięki zwiększaniu przesuniecia (zmienna i) względem początku tablicy. Na jedno wychodzi, tylko z tą różnicą, że nie zmienia się wartość wskaźnika.

komentarz 15 listopada 2015 przez Baakoma Użytkownik (780 p.)
edycja 15 listopada 2015 przez Baakoma

Niestety dalej nie wiem, czy jest dobrze, adresy się nie zgadzają, chyba się w tym wszystkim pogubiłem ;/

Czy jeśli robie przypisanie tab = newTab; to tab nie powinien mieć ten sam adres co newTab ? Dlaczego 1 i 2 tablica ma te same adresy, choć usuwam poprzednią tablicę ?

#include <iostream>

using namespace std;

void dodaj(int *t, int w, int l);

int main()
{
    int * tab = new int[10];
    for (int i = 0; i < 10; i++)
    {
        *(tab+i) = i;
        cout << "Adres pierwszej tablicy: " << (int)(tab+i)<< endl;
        cout << "Wartosc pierwszej tablicy: " << *(tab+i) << endl;
    }
    cout << endl << "Tworzenie drugiej tablicy" << endl << endl;
    delete [] tab;

    tab = new int[11];
    for (int i = 0; i < 11; i++)
    {
        *(tab+i) = i*i;
        cout << "Adres drugiej tablicy: " << (int)(tab+i) << endl;
        cout << "Wartosc drugiej tablicy: " << *(tab+i) << endl;
    }
    cout << endl << "Powiekszanie tablicy" << endl << endl;
    dodaj(tab,11,666);

    cout << endl << endl << endl;

    for (int i = 0; i < 12; i++)
    {
        cout << "Adres tablicy dla tab po zmianie: " << (int)(tab+i) << endl;
        cout << "Wartosc talibcy dla Tab po zmianie: " << *(tab+i) << endl << endl;
    }
    delete [] tab;
    return 0;
}

void dodaj(int *tab, int wielkosc, int liczba)
{
    int * newTab = new int[wielkosc+1];
    cout << "Poczatkowy newTab: " << (int)newTab << endl;
    for (int i = 0; i < wielkosc; i++)
    {
        newTab[i] = tab[i];
        cout << "Adres talibcy dla newTab: " << (int)(tab+i) << endl << endl;
        cout << "Wartosc talibcy dla newTab: " << *(newTab+i) << endl;
        cout << endl;
        cout << "Adres tablicy dla tab: " << (int)(tab+i) << endl << endl;
        cout << "Wartosc talibcy dla Tab: " << *(tab+i)<< endl;
    }
    newTab[wielkosc] = liczba;
    if(tab) delete [] tab;
    cout << "Obecny adres newTab: " << (int)newTab << endl;
    tab = newTab;
    newTab = NULL;
}

 

Podobne pytania

0 głosów
1 odpowiedź 127 wizyt
0 głosów
1 odpowiedź 257 wizyt
0 głosów
1 odpowiedź 205 wizyt

92,555 zapytań

141,402 odpowiedzi

319,546 komentarzy

61,939 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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...