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

Błąd przy kompilacji C++

Object Storage Arubacloud
0 głosów
405 wizyt
pytanie zadane 7 lipca 2017 w C i C++ przez TheFeniks Gaduła (4,690 p.)

Cześć!
Mam błąd przy kompilacji mam błąd: 

error: declaration of 'int* tab' shadows a parameter|

Kod programu:

#include <iostream>
using namespace std;

void increase( int tab[], int _size )
{
    int *copy_tab = new int[ _size  ];

    for( short i = 0; i < _size; i++ )
        copy_tab[ i ] = tab[ i ];

    delete tab;

    int *tab = new int[ _size + 1 ];

    for( short i = 0; i < _size; i++ )
        tab[ i ] = copy_tab[ i ];

    tab[ _size + 1 ] = 0;

}

void decrease( int tab[], int size_tab )
{


}


int main()
{
    int size_tab = 1;

    cout << "Podaj rozmiar tablicy: "; cin >> size_tab;

    int *tab = new int[ size_tab ];

    for( short i = 0; i < size_tab; i++ )
    {
        cout << "tab[ " << i << " ] = ";
        cin >> tab[ i ];

    }

    increase( tab, size_tab );
    size_tab = size_tab + 1;

    for( short i = 0; i < size_tab; i++ )
    {
        cout << "tab[ " << i << " ] == " << tab[ i ];

    }


 return 0;
}

Generalnie, zamysł funkcji increase był taki, że zwiększał rozmiar tablicy o 1, zaś funkcja decrease zmniejszała by o 1, ale tym się póki co nie zajmowałem, ponieważ zatrzymałem się na tej pierwszej z powodu w/w błędu. Pomysł na tą pierwszą funkcję miałem taki:  przekazujemy do niej tablicę która ma zostać zwiększona ( tab ), oraz jej rozmiar ( size_tab ). Funkcja tworzy kopie owej tablicy o tym samym rozmiarze ( copy_tab ) i przypisuje do niej wartości z oryginału. Następnie usuwa oryginału, tworzy go na nowo tylko, że o jedną szufladkę więcej, przypisuje wartości z kopi oryginału, do ostatniej szufladki przypisuje wartość 0, ponieważ jest ona "nowa".

To co wyżej napisałem, przełożyłem na "papier", no ale błąd przy kompilacji. [*]
Z góry dzięki za pomoc. :)

komentarz 7 lipca 2017 przez 10kw10 Pasjonat (22,880 p.)
uzyj vectora
komentarz 7 lipca 2017 przez TheFeniks Gaduła (4,690 p.)
Ymm... Nie umiem, nie miałem nigdy styczności z vectorami. :x

2 odpowiedzi

+1 głos
odpowiedź 7 lipca 2017 przez niezalogowany
wybrane 7 lipca 2017 przez TheFeniks
 
Najlepsza
#include <iostream>
using namespace std;

void increase( int tab[], int _size )
{
    int *copy_tab = new int[ _size  ];

    for( short i = 0; i < _size; i++ )
        copy_tab[ i ] = tab[ i ];

    delete [] tab;

    tab = new int[ _size + 1 ];

    for( short i = 0; i < _size; i++ )
        tab[ i ] = copy_tab[ i ];

    tab[ _size  ] = 0;

    delete [] copy_tab;

}

void decrease( int tab[], int size_tab )
{


}


int main()
{
    int size_tab = 1;

    cout << "Podaj rozmiar tablicy: "; cin >> size_tab;

    int *tab = new int[ size_tab ];

    for( short i = 0; i < size_tab; i++ )
    {
        cout << "tab[ " << i << " ] = ";
        cin >> tab[ i ];


    }

    increase( tab, size_tab );

    size_tab = size_tab + 1;

    cout << "\n";
    for( short i = 0; i < size_tab; i++ )
    {
        cout << "tab[ " << i << " ] == " << tab[ i ] << "\n";

    }


    delete [] tab;
    return 0;
}

Poprawnie usuwaj tablice z pamięci. Gdy chcesz przypisać pamięć już istniejącemu wskaźnikowi to nie musisz operować *. Poprawiłem też przypisywanie wartości, bo dałeś ją o 1 miejsce za daleko.

komentarz 7 lipca 2017 przez TheFeniks Gaduła (4,690 p.)
edycja 7 lipca 2017 przez TheFeniks

Super, dzięki teraz działa. No chodź nie do końca. :x

Nie mam zbytnio pomysłu co tu nawaliło. Przy na przykład rozmiarze tablicy 5, jest w porządku.

Edit: Porobiłem wypisywanie w kilku miejscach, kod wygląda tak:

#include <iostream>
using namespace std;

void increase( int tab[], int _size )
{
    int * copy_tab = new int[ _size  ];

    for( short i = 0; i < _size; i++ )
        copy_tab[ i ] = tab[ i ];

    cout << endl;
        
    for( short i = 0; i < _size; i++ )
    {
        cout << "1) copy_tab[ " << i << " ] == " << copy_tab[ i ] << endl;
        cout << "1) tab[ " << i << " ] == " << tab[ i ] << endl;

    }

    cout << endl;

    delete [ ] tab;

    tab = new int[ _size + 1 ];

    for( short i = 0; i < _size; i++ )
    {
        cout << "2) copy_tab[ " << i << " ] == " << copy_tab[ i ] << endl;
        cout << "2) tab[ " << i << " ] == " << tab[ i ] << endl;

    }

    cout << endl;

    for( short i = 0; i < _size; i++ )
        tab[ i ] = copy_tab[ i ];

    cout << endl;

    for( short i = 0; i < _size; i++ )
    {
        cout << "3) copy_tab[ " << i << " ] == " << copy_tab[ i ] << endl;
        cout << "3) tab[ " << i << " ] == " << tab[ i ] << endl;

    }

    tab[ _size  ] = 0;

    delete [ ] copy_tab;

}

void decrease( int tab[], int size_tab )
{


}


int main()
{
    int size_tab = 1;

    cout << "Podaj rozmiar tablicy: "; cin >> size_tab;

    int *tab = new int[ size_tab ];

    for( short i = 0; i < size_tab; i++ )
    {
        cout << "tab[ " << i << " ] = ";
        cin >> tab[ i ];


    }

    increase( tab, size_tab );

    size_tab = size_tab + 1;

    cout << endl << endl;

    for( short i = 0; i < size_tab; i++ )
    {
        cout << "tab[ " << i << " ] == " << tab[ i ] << "\n";

    }


    delete [] tab;
    return 0;
}

Program wypluwa to:

Podaj rozmiar tablicy: 10
tab[ 0 ] = 0
tab[ 1 ] = 1
tab[ 2 ] = 2
tab[ 3 ] = 3
tab[ 4 ] = 4
tab[ 5 ] = 5
tab[ 6 ] = 6
tab[ 7 ] = 7
tab[ 8 ] = 8
tab[ 9 ] = 9

1) copy_tab[ 0 ] == 0
1) tab[ 0 ] == 0
1) copy_tab[ 1 ] == 1
1) tab[ 1 ] == 1
1) copy_tab[ 2 ] == 2
1) tab[ 2 ] == 2
1) copy_tab[ 3 ] == 3
1) tab[ 3 ] == 3
1) copy_tab[ 4 ] == 4
1) tab[ 4 ] == 4
1) copy_tab[ 5 ] == 5
1) tab[ 5 ] == 5
1) copy_tab[ 6 ] == 6
1) tab[ 6 ] == 6
1) copy_tab[ 7 ] == 7
1) tab[ 7 ] == 7
1) copy_tab[ 8 ] == 8
1) tab[ 8 ] == 8
1) copy_tab[ 9 ] == 9
1) tab[ 9 ] == 9

2) copy_tab[ 0 ] == 0
2) tab[ 0 ] == 15077120
2) copy_tab[ 1 ] == 1
2) tab[ 1 ] == 15077816
2) copy_tab[ 2 ] == 2
2) tab[ 2 ] == -1010646592
2) copy_tab[ 3 ] == 3
2) tab[ 3 ] == -943274556
2) copy_tab[ 4 ] == 4
2) tab[ 4 ] == -875902520
2) copy_tab[ 5 ] == 5
2) tab[ 5 ] == -808530484
2) copy_tab[ 6 ] == 6
2) tab[ 6 ] == -741158448
2) copy_tab[ 7 ] == 7
2) tab[ 7 ] == -673786412
2) copy_tab[ 8 ] == 8
2) tab[ 8 ] == -606414376
2) copy_tab[ 9 ] == 9
2) tab[ 9 ] == -539042340


3) copy_tab[ 0 ] == 0
3) tab[ 0 ] == 0
3) copy_tab[ 1 ] == 1
3) tab[ 1 ] == 1
3) copy_tab[ 2 ] == 2
3) tab[ 2 ] == 2
3) copy_tab[ 3 ] == 3
3) tab[ 3 ] == 3
3) copy_tab[ 4 ] == 4
3) tab[ 4 ] == 4
3) copy_tab[ 5 ] == 5
3) tab[ 5 ] == 5
3) copy_tab[ 6 ] == 6
3) tab[ 6 ] == 6
3) copy_tab[ 7 ] == 7
3) tab[ 7 ] == 7
3) copy_tab[ 8 ] == 8
3) tab[ 8 ] == 8
3) copy_tab[ 9 ] == 9
3) tab[ 9 ] == 9


tab[ 0 ] == 15078040
tab[ 1 ] == 15077936
tab[ 2 ] == 2
tab[ 3 ] == 3
tab[ 4 ] == 4
tab[ 5 ] == 5
tab[ 6 ] == 6
tab[ 7 ] == 7
tab[ 8 ] == 8
tab[ 9 ] == 9
tab[ 10 ] == 1918557168

 

komentarz 7 lipca 2017 przez niezalogowany
edycja 7 lipca 2017

Już poprawiam:

#include <iostream>
using namespace std;

void increase( int*& tab, int& _size )
{
    int *copy_tab = new int[ _size  ];

    for( short i = 0; i < _size; i++ )
        copy_tab[ i ] = tab[ i ];

    delete [] tab;

    tab = new int[ _size + 1 ];

    for( short i = 0; i < _size; i++ )
        tab[ i ] = copy_tab[ i ];

    cout<<tab<<endl;

    tab[ _size  ] = 0;

    delete [] copy_tab;
    _size++;
}

int main()
{
    int size_tab = 1;

    cout << "Podaj rozmiar tablicy: "; cin >> size_tab;

    int *tab = new int[ size_tab ];

    for( short i = 0; i < size_tab; i++ )
    {
        cout << "tab[ " << i << " ] = ";
        cin >> tab[ i ];


    }

    increase( tab, size_tab );

    cout<< tab;

    cout << "\n";
    for( short i = 0; i < size_tab; i++ )
    {
        cout << "tab[ " << i << " ] == " << tab[ i ] << "\n";

    }


    delete [] tab;
    return 0;
}

Zapomniałem wysłać tablicy przez referencję. Zmieniłem też miejsce zwiększania zmiennej size_tab, aby funkcja była wygodniejsza ;)

komentarz 7 lipca 2017 przez niezalogowany
Tak ogólnie gwiazdka to wskaźnik (tablica), a referencja oznacza dostęp do modyfikowania oryginalnej wartości.
komentarz 7 lipca 2017 przez TheFeniks Gaduła (4,690 p.)

Działa wszystko jak marzenie, wielkie dzięki! :)

+2 głosów
odpowiedź 7 lipca 2017 przez mokrowski Mędrzec (155,460 p.)
Mogę wiedzieć z jakiego źródła się uczysz? Tak czy siak zapoznaj się jak najszybciej z vectorem. Takich technik ucz się na późniejszym etapie. Teraz robisz sobie autentyczną krzywdę we własnej edukacji (mówię jak najbardziej poważnie). Problemów z takim kodem będzie bardzo wiele.
komentarz 7 lipca 2017 przez TheFeniks Gaduła (4,690 p.)
No cóż, z różnych, z internetu, kursów przeróżnych ( Zelent, cpp0x ), przeróżne fora. Ostatnio się nie uczę tak jak na początku, tylko jak czegoś potrzebuje to google, lub książka którą mam ( Język C++ Szkoła programowania Stephen Prata, wydanie VI ), tyle.

Dlaczego robię sobie krzywdę, złe nawyki sobie przyswajam, czy jak? :p
Co do vectora, to zapoznam się.

Dzięki. :)
1
komentarz 7 lipca 2017 przez mokrowski Mędrzec (155,460 p.)
edycja 7 lipca 2017 przez mokrowski

Dobrze, pokażę jakie mogą być problemy z tym kodem nawet jeśli (trochę) go poprawić. To nie będzie idealne rozwiązanie a raczej w celu uzmysłowienia w jakie autentyczne bagno się pakujesz :-/

#include <iostream>
#include <ciso646> // To po to by nie stosować || i && a and i or
#include <cstring> // Dla memcpy(...)

using namespace std;

// 1) _size jest typu size_t
// 2) tab przekazuj przez wskaźnik
void increase(int *tab, size_t _size) {
    // new bez nothrow rzuca wyjątkiem
    int* copy_tab = new(nothrow) int[ _size + 1 ];

    // Sprawdzamy czy udała się alokacja
    if(not copy_tab) {
        std::cerr << "Alokacja pamięci na większą tablicę nie powiodła się.\n";
        return;
    }
    // Bo po co kopiować for'em jak jest funkcja?
    memcpy(copy_tab, tab, _size);
    // Zerowanie ostatniego elementu
    copy_tab[_size] = 0;
    tab = copy_tab;
    delete [] copy_tab;
}

void decrease(int *tab, size_t size_tab) {
}


int main() {
    size_t size_tab = 1;
    cout << "Podaj rozmiar tablicy: ";
    // A co jak wpiszę swoje imie? Co ma zrobić program?
    cin >> size_tab;
    // Znów nothrow
    int* tab = new(nothrow) int[ size_tab ];

    if(not tab) {
        std::cerr << "Alokacja pamięci na tablicę nie powiodła się.\n";
        // Oczywiście że lepiej zwrócić EXIT_FAILURE z <cstdlib>
        return -1;
    }
    // Znów size_t
    for(size_t i = 0; i < size_tab; ++i) {
        cout << "tab[ " << i << " ] = ";
        // A co jak wpiszę imie?
        cin >> tab[ i ];
    }

    // A co jak increse się nie powiedzie?
    increase(tab, size_tab);
    // No to jak increse(..) się nie powiedzie to za chwilę będziesz
    // czytał jakieś "buraki" z pamięci :-/
    size_tab = size_tab + 1;

    // Nie short a size_t
    for(size_t i = 0; i < size_tab; ++i) {
        cout << "tab[ " << i << " ] == " << tab[ i ];
    }

    // W main w C++ nie jest to niezbędne
    return 0;
}

 

komentarz 7 lipca 2017 przez niezalogowany
#mokrowski czy w obecnym standardzie (C++30) do zerowania ostatniej wystarczy przesyłanie tablicy przez wskaźnik dla wyzerowania ostatniej wartości?
komentarz 7 lipca 2017 przez mokrowski Mędrzec (155,460 p.)
edycja 7 lipca 2017 przez mokrowski

Jeśli pytasz poważnie to standard C++ od początku zapewniał poprawność arytmetyki wskaźników na zakresie od początku tablicy do jej ostatniego elementu + 1. Stąd takie przesyłanie przestrzeni pamięci będzie działało ale funkcja nie ma pojęcia gdzie.... i co pisze a co gorsza nie wie czy może pisać :-/ Jak widzisz w 21 linii ja ostatnią wartość zeruję mając nadzieję że ktoś/gdzieś poprawnie alokował tę pamięć :-/ 

A jeszcze poważniej ... sam wiesz że tak pisany kod i tak jest i tak do d* i został by wyrzucony na 1 przeglądzie. Sam bym go wysłał do /dev/null :-)

komentarz 7 lipca 2017 przez niezalogowany
edycja 7 lipca 2017
Właśnie w Twoim kodzie wartość nie zeruje się dla większych rozmiarów tablic (np. 10). Nie wiem czy wina leży po stronie mojego oprogramowania. Czy moje rozwiązanie problemu (to późniejsze) jest dobre i w miarę bezpieczne? Albo czy sam dobrze je rozumiem?

Oczywiście na miarę potrzeb, bo przecież wiadome, że kod nie jest zaawansowany. Nie zawiera obsługi błędów, ale przynajmniej robi to co zostało nakreślone.
komentarz 7 lipca 2017 przez TheFeniks Gaduła (4,690 p.)

O istnieniu funkcji memcpy nie miałem pojęcia, no ale teraz już mam, dzięki! :D

Generalnie, nie miałem zamiaru wprowadzać do tego programu walidacji błędów, bo zwyczajnie tego nie potrzebuje. Chciałem tylko stworzyć funkcję która powiększa mi rozmiar tablicy o 1, oraz zmniejsza o 1, owe funkcje będą mi potrzebne w innych programach. :D

Dzięki wielkie za pomoc, pozdrawiam! :)

Edit: Hipcio, dokładnie kod robi to co miałem za cel zrobić, obsługa błędów jest zbędna, bo ja tylko z tego korzystam, i korzystać będę. :P

Podobne pytania

0 głosów
1 odpowiedź 220 wizyt
0 głosów
1 odpowiedź 185 wizyt

92,570 zapytań

141,422 odpowiedzi

319,643 komentarzy

61,958 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!

...