W08 dynamiczna alokacja pamieci

W08 dynamiczna alokacja pamieci, PWR - Informatyka W4, podstawy programowania
[ Pobierz całość w formacie PDF ]
DYNAMICZNE PRZYDZIELANIE PAMIECI
Pamięć komputera, dostępna dla programu, dzieli się na cztery obszary:
·
kod programu
,
·
dane
statyczne
( np. stałe i zmienne globalne programu),
·
dane
automatyczne
®
zmienne tworzone i usuwane automatycznie przez kompilator
na tzw.
stosie
(
ang. stack
) np. zmienne lokalne wewnątrz funkcji
void przykladowa_funkcja(void)
{
float zmienna_lokalna;
zmienna_lokalna=10;
}
·
dane
dynamiczne
®
organizowane przez menadŜera-zarządcę pamięci dynamicznej,
moŜna je tworzyć i usuwać w dowolnym momencie pracy programu,
w pamięci wolnej komputera
®
na tzw.
stercie
(
ang. heap
)
Zmienne dynamiczne:
®
odpowiedzialnym za ich utworzenie (rezerwację pamięci)
oraz za ich usunięcie (zwolnienie pamięci)
jest programista !!!
®
dostęp do takiej zmiennej moŜliwy jest jedynie poprzez jej adres w pamięci
(przechowywany w zmiennej wskaźnikowej)
®
korzystanie z nieprzydzielonego obszaru najprawdopodobniej spowoduje błąd!
®
próba zwolnienia juŜ zwolnionego obszaru spowoduje błąd!
Przykład
®
ilustracja czasu „Ŝycia” zmiennych
zmienna statyczna
«
komputer na własność (cały czas)
zmienna lokalna
«
komputer w laboratorium (tylko na czas zajęć)
zmienna dynamiczna
«
komputer z wypoŜyczalni (na dowolny czas)
Dostęp do
obiektu
za pomocą
wska
ź
nika-adresu-odsyłacza
WSKA
Ź
NIK
®
OBIEKT
numer telefonu
®
telefon
adres internetowy
®
strona HTML na serwerze
adres pocztowy
®
mieszkanie
numer PESEL
®
Kowalski Jan
numer pokoju
®
wynajęty apartament w hotelu
numerek z szatni
®
dynamicznie przydzielone miejsce-wieszak w szatni
M. Piasecki, JĘZYKI PROGRAMOWANIA (1)
-
1
-
Dynamiczne przydzielanie pamięci
 W języku „
C
” do dynamicznego przydzielania pamięci (tworzenia zmiennych
dynamicznych) słuŜyły specjalne funkcje z bibliotek:
<alloc.h>
lub
<stdlib.h>
void
*
malloc(
size_t
rozmiar );
//
przydział bloku o zadanej wielkosci
void
*
calloc(
size_t
il_elementow,
size_t
rozmiar);
//
przydział tablicy
void
*
realloc(
void
* stary_wskaznik,
size_t
nowy_rozmiar); //
zmiana wielko
ś
ci
void
free(
void
*
wskaznik);
//
zwolnienie wskazywanego obszaru
np.
void
main(
void
)
{
int
*
wsk; //
zmienna wska
ź
nikowa do zapami
ę
tania adresu liczby
int
·
·
·
wsk = (
int
*
) malloc( sizeof(
int
) );
//
przydzielenie pami
ę
ci na liczb
ę
int
if
( wsk == NULL )
{
printf( ”

ą
d przydziału pami
ę
ci
” );
return
;
·
·
·
*
wsk = 10;
//
przykładowe operacje na dynamicznej liczbie
int
*
wsk
*
= 2;
printf( ”%d”,
*
wsk );
scanf( ”%d”, wsk );
·
·
·
free( wsk );
//
zwolnienie pami
ę
ci przed zako
ń
czeniem programu
}
Przykład operacji na dynamicznej tablicy o dowolnej ilo
ś
ci elementów:
np.
void
main(
void
)
{
int
rozmiar_tablicy;
double
*
tablica_liczb;
printf( ”
Ile liczb chcesz wprowadzi
ć
:
” );
scanf( ”%d”, &rozmiar_tablicy );
if
( tablica_liczb = (
double
*
) calloc( rozmiar_tablicy, sizeof(double) ) )
{
for( int i = 0; i
<
rozmiar_tablicy, i++ );
*
( tablica_liczb+i ) = 100;
//
tablica_liczb[ i ] = 100;
·
·
·
free( tablica_liczb );
}
}
M. Piasecki, JĘZYKI PROGRAMOWANIA (1)
-
2
-
Dynamiczne przydzielanie pamięci
” do dynamicznego przydzielania pamięci
moŜna nadal wykorzystywać funkcje z biblioteki <alloc.h>
ale duŜo lepiej jest korzystać z nowych operatorów:
new
oraz
delete
++
<wskaźnik_na_obiekt> =
new
<typ_obiektu> [
parametry_inicjalizacyjne
] ;
delete
<wskaźnik_na_obiekt> ;
np.
int
*
wsk ;
// wska
ź
nik na zmienn
ą
typu całkowitego
wsk =
new int
;
// utworzenie nowego obiektu (nowej zmiennej
int
)
if
( wsk != NULL )
{
*
wsk = 10 ;
// przypisanie warto
ś
ci (poprzez wska
ź
nik)
printf( ”%d” ,
*
wsk );
// wydrukowanie zawarto
ś
ci zmiennej dynam.
·
·
·
delete
wsk
;
// usuni
ę
cie zmiennej dynam. (zwolnienie pami
ę
ci)
}
Porównanie utworzenia zwykłej tablicy i tablicy dynamicznej:
//
operacja utworzenia zwykłej tablicy
const
ROZMIAR_TABLICY = 100;
double
zwykła_tablica[ ROZMIAR_TABLICY ];
//
operacja utworzenia i zwolnienia tablicy dynamicznej
int
rozmiar_tablicy;
cout <<

Ile liczb chcesz wprowadzi
ć
:
” ;
cin >> rozmiar_tablicy ;
double
*
tablica_dynamiczna;
tablica_dynamiczna =
new double
[ rozmiar_tablicy ];
·
·
·
for(
int
i=0; i<rozmiar_tablicy; i++)
tablica_dynamiczna[ i ] = 10.5;
·
·
·
for(
int
i=0; i<rozmiar_tablicy; i++)
cout<<endl<<”
tablica[
” << i+1 << ”
]=
” << tablica_dynamiczna[ i ];
·
·
·
delete
[ ] tablica_dynamiczna;
M. Piasecki, JĘZYKI PROGRAMOWANIA (1)
-
3
-
Dynamiczne przydzielanie pamięci
W języku „
C
Przykład 1
- pojedyncza realokacja (zmiana rozmiaru) tablicy jednowymiarowej
void
main( )
{
//
utworzenie 10-cio elementowej tablicy zawieraj
ą
cej liczby z przedziału -50
¸
50
int
rozmiar=10;
long
* tablica =
new long
[ rozmiar ];
for
(
int
i=0; i< rozmiar; i++)
tablica[ i ] = random(101)-50;
cout<<endl<<"
Zawartosc tablicy po wylosowaniu elementów:
"<<endl;
for
(
int
i=0; i<rozmiar ; i++)
cout << endl <<"
tab[
" << i << "
]=
" << tablica[ i ];
cout<<endl<<"
Rozmiar tablicy:
"<<rozmiar<<endl;
//
policzenie ile z wylosowanych liczb ma dodatni
ą
warto
ść
int
ilosc_dodatnich=0;
for
(
int
i=0; i<rozmiar; i++)
if
( tablica[i]>0 )
ilosc_dodatnich++;
//
usuni
ę
cie wszystkich liczb ujemnych
®
z jednoczesnym zmniejszeniem tablicy
long
* nowa_tablica =
new long
[ilosc_dodatnich];
if
( nowa_tablica==NULL )
cout<<"
UWAGA - blad tworzenia nowej tablicy
";
else
{
int
j=0;
for
(
int
i=0;i<rozmiar;i++)
if
( tablica[i]>0 )
{
nowa_tablica[ j ]=tablica[ i ];
j++;
}
delete
[ ] tablica;
tablica=nowa_tablica;
rozmiar=ilosc_dodatnich;
}
cout<<endl<<"
Zawartosc tablicy po usunieciu liczb ujemnych:
"<<endl;
for
(
int
i=0; i<rozmiar ; i++)
cout << endl <<"
tab[
" << i << "
]=
" << tablica[ i ];
cout<<endl<<"
Rozmiar tablicy:
"<<rozmiar<<endl;
cin.get();
delete
[ ] tablica;
}
M. Piasecki, JĘZYKI PROGRAMOWANIA (1)
-
4
-
Dynamiczne przydzielanie pamięci
 Przykład (2)
– inna wersja programu przykład (1)
®
z wykorzystaniem funkcji
bool
USUN_UJEMNE(
long
* &wsk_tablicy,
int
&rozmiar_tablicy)
{
int
ilosc_dodatnich=0;
for
(
int
i=0; i<rozmiar_tablicy; i++)
if
( wsk_tablicy[i]>0 )
ilosc_dodatnich++;
long
* nowa_tablica =
new long
[ilosc_dodatnich];
if
( nowa_tablica==NULL )
return
false
;
int
j=0;
for
(
int
i=0; i<rozmiar_tablicy; i++)
if
( wsk_tablicy[i]>0 )
{
nowa_tablica[ j ]=wsk_tablicy[ i ];
j++;
}
delete
[ ] wsk_tablicy;
wsk_tablicy=nowa_tablica;
rozmiar_tablicy=ilosc_dodatnich;
return true
;
}
long
* LOSUJ_UJEMNE_i_DODATNIE(
int
ilosc_liczb)
void
WYSWIETL(
long
* tablica,
int
rozmiar_tablicy);
bool
USUN_UJEMNE(
long
* &wsk_tablicy,
int
&rozmiar_tablicy);
void
main( )
{
int
n=10;
long
*tablica = LOSUJ_UJEMNE_i_DODATNIE (n);
WYSWIETL( tablica,n);
cin.get();
if
( USUN_UJEMNE(tablica,n)==
false
)
cout<<"
UWAGA - blad operacji usuwania ujemnych
";
cout<<endl<<endl<<"
Po wywolaniu funkcji USUN_UJEMNE:
"<<endl;
WYSWIETL( tablica,n);
cin.get();
delete
[ ] tablica;
}
M. Piasecki, JĘZYKI PROGRAMOWANIA (1)
-
5
-
Dynamiczne przydzielanie pamięci
[ Pobierz całość w formacie PDF ]
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • diabelki.xlx.pl
  • Podobne
    Powered by wordpress | Theme: simpletex | © Spojrzeliśmy na siebie szukając słów, które nie istniały.