Wskaźniki - zadanie z Symfonii do sprawdzenia

2014-09-12 08:48
0

Treść zadania:
Napisz program, w którym w funkcji main zostaną stworzone (operatorem new) trzy tablice typu double o rozmiarach co najmniej 20 elementów. Elementy pierwszych dwóch tablic załaduj jakimiś wartościami. W programie powinna być funkcja, która przyjmie wysłane do niej te trzy tablice. Funkcja ta ma na elementach tych tablic wykonać operację mnożenia - taką, że i-ty elementu tablicy pierwszej zostanie pomnożony przez i-ty element tablicy drugiej. Rezultat ma zostać wpisany do i-tego elementu tablicy trzeciej.
W funkcji main wypisz na ekranie zawartość poszczególnych elementów tablicy pierwszej,drugiej i trzecie, a następnie skasuj te tablice.

Daje mój kod. Chciałem spytać czy dobrze to zrobiłem ? Bo przy usuwaniu tablic pojawia mi się okienko konsolowe z błędem Microsoft C++ Deubug library.Zdjęcie:user image

Kod:

#include <iostream>
using namespace std;
void zaladuj(double *wskaznik,int ile);
void operacja(double *wsk, double *wsk1, double *wsk2, int ile);
int main()
{
    double *wskaznik0, *wskaznik1, *wskaznik2;
    wskaznik0 = new double [20];
    wskaznik1 = new double [20];
    wskaznik2 = new double [20];
    zaladuj(wskaznik0,20);
    zaladuj(wskaznik1,20);
    operacja(wskaznik0,wskaznik1,wskaznik2,20);

    for(int i = 0; i < 20; i ++, wskaznik0++, wskaznik1++, wskaznik2++)
    {
        cout << *wskaznik0 << "\t" << *wskaznik1 << "\t" << *wskaznik2 << endl;
    }
    delete[] wskaznik0;
    delete[] wskaznik1;
    delete[] wskaznik2;

    system("pause");
}
void zaladuj(double *wskaznik,int ile)
{
    for(int i = 0; i < ile ; i++, wskaznik++)
    {
        *wskaznik = i;
    }

}
void operacja(double *wsk, double *wsk1, double *wsk2, int ile)
{
    for(int i = 0; i < ile; i ++, wsk++, wsk1++, wsk2++)
    {
        *wsk2 = (*wsk) * (*wsk1);
    }
} 

Pozostało 580 znaków

2014-09-12 10:07
0

Poprzednia moja odpowiedź była błędna:)
Problemem jest to że powinieneś zwalniać tablice jednowymiarową przez delete wskaźnik. Do tego w pętli for wyświetlającej zawartość dodatkowo zmieniasz wartość wskaźnika i robi się segmentacja pamięci:)

Zmień ostatnie linie w mainie i powinno działać

     for(int i = 0; i < 20; i ++)
    {
        cout << *(wskaznik0+i) << "\t" << *(wskaznik1+i) << "\t" << *(wskaznik2+i) << endl;
    }
    delete wskaznik0;
    delete wskaznik1;
    delete wskaznik2;
Tak tablicy sie nie zwalnia... - lookacode1 2014-09-12 10:10
Jeśli alokujesz za pomocą new[] to musisz zwolnić za pomocą delete[]. Jednakże samo używanie new/new[] jest złą praktyką i powinno się jej unikać, szczególnie będąc nowicjuszem. - kq 2014-09-12 10:46

Pozostało 580 znaków

2014-09-12 10:15
1
for(int i = 0; i < ile; i ++, wsk++, wsk1++, wsk2++)
{
*wsk2 = (*wsk) * (*wsk1);
} 

Co to za dziwne nawyki?
W ten wlasnie sposob przekraczasz przydzielona tablice...
Problem nie tkwil w zwalnianiu pamieci -> http://ideone.com/qFwHES

Pozostało 580 znaków

2014-09-12 11:15
0

Nie bardzo rozumiem ten mój błąd.
W pętli for dodaje do wsk++, aby w następnym obiegu pętli pokazał o jeden wskaźnik dalej. Bo ten wskaźnik pokazuje na zerowy element tablicy, więc w instrukcji for wykonuje instrukcję dla takich samych elementów dla każdej tablicy.

Pozostało 580 znaków

2014-09-12 11:18
kq
1
nowicjusz35 napisał(a):

Nie bardzo rozumiem ten mój błąd.
W pętli for dodaje do wsk++, aby w następnym obiegu pętli pokazał o jeden wskaźnik dalej. Bo ten wskaźnik pokazuje na zerowy element tablicy, więc w instrukcji for wykonuje instrukcję dla takich samych elementów dla każdej tablicy.

@lookacode1 zacytował zły fragment, ale to faktycznie nietypowa obsługa fora Cię zgubiła.

W funkcji main masz:

    wskaznik0 = new double [20];
    wskaznik1 = new double [20];
    wskaznik2 = new double [20];
    // ...
    for(int i = 0; i < 20; i ++, wskaznik0++, wskaznik1++, wskaznik2++)
    {
        // ...
    }

    delete[] wskaznik0;
    delete[] wskaznik1;
    delete[] wskaznik2;

Czyli delete[] podajesz inny (o 20 miejsc) wskaźnik, niż otrzymany z new[].


edytowany 2x, ostatnio: kq, 2014-09-12 11:19
aha czyli już rozumiem dzięki, gdybym te tablice stworzył normalnie bez operatora new, to mój program byłby w porządku ? - nowicjusz35 2014-09-12 11:25
Nie, wskaznik0++, wskaznik1++, wskaznik2++ by się nie skompilowało. - kq 2014-09-12 11:27
dlaczego ? przecież wtedy normalnie bym mógł przesuwać to na co pokazuje wskaźnik i wyświetlić potem rezulataty. A potem nie muszę przecież zwalniać pamieci. - nowicjusz35 2014-09-12 11:42
Ach, być może źle Cię zrozumiałem. Gdybyś zdefiniował wskaznik0 jakodouble wskaznik0[20] to by się nie skompilowało. Gdybyś po prostu przypisał początek 20-elementowej tablicy do niego, to by było ok. Ale i tak spójrz na indeksację u @lookacode1 - tak jest dużo lepiej. - kq 2014-09-12 11:45

Pozostało 580 znaków

2014-09-12 12:05
0
    wskaznik0 = new double [20];
    wskaznik1 = new double [20];
    wskaznik2 = new double [20];
    // ...
    for(int i = 0; i < 20; i ++, wskaznik0++, wskaznik1++, wskaznik2++)
    {
        // ...
    }

    delete[] wskaznik0-20;
    delete[] wskaznik1-20;
    delete[] wskaznik2-20;

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2014-09-13 12:31
0

jeszcze raz wracam do tego programu, moja funkcja zaladuj też była zła, prawda ? Ponieważ przesunąłem wskaźnik ?

Pozostało 580 znaków

2014-09-13 13:08
kq
1

Nie, była poprawna¹ ponieważ do funkcji kopiowałeś wskaźniki, przez co operowałeś na ich kopiach, nie zmieniając oryginałów.

¹ ale wciąż nietypowa, lepiej by było, gdybyś po prostu używał indeksów.


Pokaż pozostałe 3 komentarze
Nie. Przekazując coś do funkcji przez kopię (a tak właśnie robiłeś) kopiujesz to, więc jakiekolwiek zmiany są przeprowadzane na kopii. Ty kopiowałeś wskaźnik, więc zmiany dotyczyły tylko jego kopii. - kq 2014-09-13 18:01
to moja funkcja zaladuj i operacja jest dobra ? Tylko błąd popełniłem w pętli for ? Raczej nie będę tak pisał funkcji tylko chce wiedzieć czy popełniłem błąd w tych funkcjach czy tylko w pętli for. - nowicjusz35 2014-09-14 12:48
Wszystkie Twoje pętle for zachowują się tak samo, ale tylko w jednym przypadku jest to zabójcze dla programu. - kq 2014-09-14 12:59
wiem właśnie, że w moim programie popełniłem błąd w pętli for, bo przesunąłem wskaźniki, więc potem był problem ze zwolnieniem pamięci. Ale chciałem spytać czy jeśli bym zmienił funkcję for bez przesuwania wskaźników, a funkcje zostawił bez zmian to czy program by był dobry ? Tylko chcę to wiedzieć tak dla siebie - nowicjusz35 2014-09-14 13:32
Tak jak pisałem: tak, nie wywalałby się i działałby zgodnie z założeniami. Ale fory w funkcjach wciąż by były dziwne :) - kq 2014-09-14 13:36

Pozostało 580 znaków

Liczba odpowiedzi na stronę

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