Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Kopiowanie danych do większej tablicy dynamicznej

Ostatnio zmodyfikowano 2014-12-01 15:43
Autor Wiadomość
Malina94
Temat założony przez niniejszego użytkownika
Kopiowanie danych do większej tablicy dynamicznej
» 2014-11-30 15:06:21
Witam! Co jest nie tak w poniższym kodzie? Przy pierwszym przepisaniu pojawiają się krzaki. Późniejsze dopisanie przebiega już dobrze.

C/C++
#include <iostream>

using namespace std;

struct abcd {
    char x;
};

void powieksz( int licznik, abcd * historia, int a );

int main() {
   
    int a = 5;
    abcd * historia = new abcd[ a ];
    int licznik = 0;
    char liczba;
   
    while( 1 ) {
       
        cin >> liczba;
       
        historia[ licznik ].x = liczba;
        licznik++;
        powieksz( licznik, historia, a );
       
       
        cout << "ZAWARTOSC:" << endl;
        for( int i = 0; i < licznik; i++ ) { //wyswietlam co sie dodalo
            cout << historia[ i ].x << " ";
        }
        cout << endl;
    }
   
}

void powieksz( int licznik, abcd * historia, int a )
{
    int b;
    if( licznik == a ) { //jesli skonczy mi sie miejsce w mojej tablicy
        b = a * 2;
        abcd * temp = new abcd[ b ]; //to tworze tablice tymczasowa o podwojonej ilosci komorek
       
        for( int i = 0; i < a; i++ ) {
            temp[ i ].x = historia[ i ].x; //przepisuje zawartosc mojej tablicy do tymczasowej
        }
       
        delete[] historia; //kasuje tablice
        a = b; //zmieniam rozmiar zmiennej
       
        abcd * historia = new abcd[ a ]; //tworze moja tablice o nowym rozmiarze
       
        for( int i = 0; i < a; i++ ) {
            historia[ i ].x = temp[ i ].x; //przepisuje moje dane
        }
       
        delete[] temp; //kasuje tymczasowa tablice
    }
   
}
P-121750
darko202
» 2014-11-30 21:15:48
C/C++
void powieksz( int licznik, abcd * historia, int a );

int main() {
   
    int a = 5;
    ....
    powieksz( licznik, historia, a );
   
    cout << a; // dodaj to 
    ...
}
}

void powieksz( int licznik, abcd * historia, int a )
{
int b;
...
a = b; //zmieniam rozmiar zmiennej
....
}

nie mam kompilatora aby puścić Twój kod, ale popatrz to co zostawiłem wyżej
wydaje mi się że zmienna tak przekazana jest kopiowana i wykonujesz zmiany na kopii, a nie orginalnej zmienne
nie ulega zmianie - dodaj po wywołanu metody powiększ
 cout << a;
 

2
//to tworze tablice tymczasowa o podwojonej ilosci komorek
//przepisuje zawartosc mojej tablicy do tymczasowej
//kasuje tablice
-- to wystarczyłoby bo co jest istotnego dla tablicy tymczasowej  -> wskaźnik na elemet pierwszy
historia = temp; // załatwia to co robisz później

//zmieniam rozmiar zmiennej
//tworze moja tablice o nowym rozmiarze
//przepisuje moje dane
//kasuje tymczasowa tablice


nie rozumiem co oznacza sypie mi krzaki, ale przeważnie oznacz że wyswietla jakieś miejsce w pamieci.
P-121778
Maciek
» 2014-11-30 21:18:38
Z ciekawości zapytam - czy nie możesz wykorzystać jakiegoś kontenera z biblioteki STL ??
P-121780
Malina94
Temat założony przez niniejszego użytkownika
» 2014-11-30 21:40:06
Zmieniłam trochę i teraz do funkcji podaję wskaźnik na 'a'. Jeśli chodzi o krzaki, to dostaję coś takiego: http://screenshooter.net/5472572/isrfyol

Maciek - nie mogę. STL mam całkowicie zabronione.
P-121790
Malina94
Temat założony przez niniejszego użytkownika
» 2014-11-30 21:43:20
Spróbowałam tak:
C/C++
void powieksz( int licznik, abcd * historia, int * wsk_a )
{
    int b;
    if( licznik == * wsk_a ) { //jesli skonczy mi sie miejsce w mojej tablicy
        b =( * wsk_a ) * 2;
        abcd * temp = new abcd[ b ]; //to tworze tablice tymczasowa o podwojonej ilosci komorek
       
        for( int i = 0; i < * wsk_a; i++ ) {
            temp[ i ].x = historia[ i ].x; //przepisuje zawartosc mojej tablicy do tymczasowej
        }
       
        //delete[] historia; //kasuje tablice
        //*wsk_a = b; //zmieniam rozmiar zmiennej
       
        //abcd *historia = new abcd[*wsk_a]; //tworze moja tablice o nowym rozmiarze
       
        for( int i = 0; i < * wsk_a; i++ ) {
            historia[ i ].x = temp[ i ].x; //przepisuje moje dane
        }
       
        //delete[] temp; //kasuje tymczasowa tablice
    }
   
}

Teraz działa :)
Dziękuję za pomoc.
P-121791
darko202
» 2014-12-01 08:20:51
Niestety nadal ma 2 błędy
1. tzw. wycieki pamięci
jeśli zarezerwujesz pamięć przy pomocy new powinieneś to zwolnić delete
delete zwalnia pamięć a nie usuwa samą zmienną
 

2. nieefektywny algorytm
rezerwując pamięć na nową tablicę  otrzymujemy ciągły obszar
dlatego po przekopiowaniu wartości do nowej tablicy
wystarczy zmienić wskaźnik na pierwszy element tablicy - reszta to zbędne kroki

przy dużej wielkości tablicy Twój program wykona odpowiednio dużą ilość niepotrzebnych operacji.
P-121809
Malina94
Temat założony przez niniejszego użytkownika
» 2014-12-01 12:36:22
Czyli pamięć której tablicy powinnam kasować za pomocą delete? Tymczasowej?
A wskaźnik na pierwszy element, to chodzi o ten zapis, co ktoś wyżej napisał: historia = temp; ?

Niby coś takiego też działa:
C/C++
void powieksz( int licznik, abcd * historia, int * wsk_a )
{
    int b;
    if( licznik == * wsk_a ) { //jesli skonczy mi sie miejsce w mojej tablicy
        b =( * wsk_a ) * 3;
        abcd * temp = new abcd[ b ]; //to tworze tablice tymczasowa o podwojonej ilosci komorek
       
        for( int i = 0; i < * wsk_a; i++ ) {
            temp[ i ].x = historia[ i ].x; //przepisuje zawartosc mojej tablicy do tymczasowej
        }
       
        historia = temp;
       
        delete[] temp;
    }
   
}
Ale przy wpisaniu większej ilości danych i przy próbie wyłączenia konsoli, ta się wiesza.
P-121816
darko202
» 2014-12-01 14:08:11
po przepisaniu wartości do tablicy pomocniczej
kasujesz zarezerwowaną pamięć tablicy podstawowej
przypisujesz zmiennej tablica podstawowa adres tablicy pomocniczej

podobnie jak w
http://cpp0x.pl/forum/temat/?id=17763

C/C++
void dodaj( A *& tab, int & x ) {
   
    A * tmp = new A[ x + 1 ]; //tymczasowa, rezerwuję nową pamieć
    for( int i = 0; i <( x ); i++ ) // przepisanie
         tmp[ i ] = tab[ i ];
   
    delete[] tab; // zwolnienie pamięci
    tmp[ x ]; // inicjacja nowego
    tab = tmp; // przypisanie
    x++; // inkrementalna
}
P-121819
« 1 » 2
  Strona 1 z 2 Następna strona