wskaźnik a pętla(wywala bład)

0

Witajcie,
mam problem taki, że chce wypełnić tablicę losowymi wartościami, ale nie chce robić tego za pomocą tab[i] tylko za pomocą wskaźników. Zrobiłem to tak jak na dole i wpisywanie w funkcji main szwankuje. Pogrubiłem to co jest nie tak. Jak zaprintuje linijkę //tablica++; wpisuje się wartość zgodnie z oczekiwaniami, jak chce żeby przeskoczył do następnego adresu i tam wrzucił wartość to wywala błąd i podkreśla mi delete [] tablica; Ma ktoś jakiś pomysł co jest nie halo?

 #include <cmath>
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>

using namespace std;

void wypisz(float *tab, int ile)
{
    for ( int i = 0; i < ile; i++)
    {
        cout << *tab << endl;
        tab++;
    }
}


float srednia(float *tab, int ile)
{
    float suma = 0;
    for (int i = 0; i < ile; i++)
    
        suma+= *tab;
        tab++;
    
    return suma / ile;
}

int main()
{
    srand((unsigned)time(NULL));
    int ile;
    ile = 0;
    cerr << "Podaj z ilu liczb chcesz obliczyć średnią" << endl;
    cin >> ile;
    
    
    float *tablica;
    tablica = new float[ile];
    
    for (int i = 0; i < ile; i++)
    {
        *tablica = 1 + rand() % 6;
        tablica++; // tu nie przesuwa
    }
    
    wypisz(tablica, ile);
    cout << "srednia wynosi = " << srednia(tablica, ile) << endl;
   delete [] tablica; // tutaj wywala
    
    
    return 0;
}
0

Ech chłopie, myśl trochę. W chwili alokacji wskaźnik tablica wskazuje na POCZĄTEK zaalokowanego bloku. Każde wykonanie ++ na tym wskaźniku PRZESUWA go, co zrozumiałe, bo przecież próbujesz wpisywać dane do kolejnych elementów. Ale potem wesoło wywołujesz funkcje która oczukuje na argument będący znów POCZĄTKIEM tablicy, a przecież twój wskaźnik po tych wszystkich ++ wskazuje na KONIEC tablicy. delete[] także oczekuje adresu POCZĄTKU zaalokowanego bloku pamięci.

0
    for (float *i=tablica;i<tablica+ile;++i) *i=1+rand()%6;
0
_13th_Dragon napisał(a):
    for (float *i=tablica;i<tablica+ile;++i) *i=1+rand()%6;

czy mogę prosić o wytłumaczenie dlaczego pętla for i później podawanie kolejnych wartości wygląda w ten sposób? nie rozumiem dlaczego znalazł się

 *i = tablica

oraz i < tablica + ile

0

A czy w: for (int i = 0; i < ile; i++)
Rozumiesz dlaczego znalazł się: i = 0
oraz: i < ile
?

1

Ech. Idea którą zaproponował @_13th_Dragon jest prosta: tworzysz lokalną kopię wskaźnika i bawisz się już tylko nią, a oryginalny wskaźnik tablica pozostaje nieruszony.

Mam wrażenie że nie do końca rozumiesz co to jest wskaźnik. Wyjaśnijmy więc to: wskaźnik to jest po prostu adres w pamięci komputera gdzie cośtam się znajduje. Pamięć komputera ma ponumerowane komórki a wskaźnik przechowuje numer komórki, nic więcej.

Po twojej alokacji wskaźnik tablica może mieć wartość 0, gdyby akurat przypadkiem zaalokowało ci pamięć na samym początku puli adresowej (to nie jest możliwe, ale to tylko przykład!). Więc zaalokowałeś komórki od 0 do X. Jak sobie wypiszesz WARTOŚĆ wskaźnika to będzie ona wynosiła 0, a jak wypiszesz wartość wskazywaną *tablica to dostaniesz wartość pod zerowym numerem komórki pamięci komputera. Wywołanie ++ powoduje zwyczajnie zwiększenie wartości, więc gdyby tablica była wskaźnikiem na 1-bajtowe zmienne to ++ sprawiłoby że wartość przeskoczyłaby z 0 na 1.
Jak więc rozwiązać problem? Utworzyć drugą zmienną i wpisać do niej tą samą wartość którą ma tablica, czyli mamy drugą zmienną np. tablica2 która też ma wartość 0 i to na niej sobie pracujemy. Efekt jest taki, że tablica cały czas ma wartość 0, czyli pokazuje na początek bloku.

0
_13th_Dragon napisał(a):

A czy w: for (int i = 0; i < ile; i++)
Rozumiesz dlaczego znalazł się: i = 0
oraz: i < ile
?

rozumiem

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