-
Data: 2014-01-15 11:19:19
Temat: Re: pryszcze...
Od: g...@g...com szukaj wiadomości tego autora
[ pokaż wszystkie nagłówki ]W dniu środa, 15 stycznia 2014 10:20:37 UTC+1 użytkownik inny punkt siedzenia...
napisał:
> a czy m�g�by� co� ciekawego napisac jeszcze o wska�nikach na wska�nik?
Nie wiem, czy to ciekawe, ale moge podac przyklad
zastosowania wskaznika na wskaznik.
Zakladam, ze wiesz, co robi funkcja printf -- pozwala
na wypisanie formatowanego tekstu na standardowe wyjscie,
np. printf("%d %s\n", 7, "samurajow") wypisze "7 samurajow"
i znak nowej linii. Specyfikator "%s" sprawia, ze jako
drugi argument funkcja pobiera wskaznik na char, co
do ktorego zaklada sie, ze wskazuje na fragment pamieci,
w ktorym znajduje sie sekwencja znakow ASCII (powiedzmy)
zakonczona znakiem '\0' (albo po prostu liczba 0, bo to
to samo), czyli tzw. "null-terminated string".
Istnieje tez nieco ogolniejsza funkcja fprintf, ktora
pozwala wybrac strumien, do ktorego bedziemy pisac.
Istnieja tez dwie funkcje, ktore pozwalaja zapisac formatowany
string do pamieci. Maja one nastepujace prototypy:
int sprintf ( char * str, const char * format, ... );
int snprintf ( char * s, size_t n, const char * format, ... );
Pierwsza z nich pobiera wskaznik na bufor, do ktorego
chcemy pisac. Na przyklad mozemy sobie wyobrazic taki
fragment kodu:
char buffer[256];
sprintf(buffer, "mam sobie string `%s` o nieznanej dlugosci!", jakas_zmienna);
Problem polega na tym, ze nie wiemy, jak dlugi jest
string wskazywany przez jakas_zmienna. W szczegolnosci
moze byc na tyle dlugi, ze nie zmiesci sie w buforze
(tzn. docelowy string bedzie mial w typ przypadku
wiecej niz 256 znakow), co moze spowodowac nadpisanie
wartosci jakichs zmiennych w tej samej przestrzeni
adresowej, co zmienna buffer. Innymi slowy, moze byc
zle, bo po 1. moze to byc przczyna trudnych do wykrycia
i nieprzewidwalnych bledow, a po 2. moze niekiedy
pozwolic jakiemus hakerowi tak spreparowac dane wejsciowe
(zakladajac, ze jakas_zmienna jest inicjalizowana danymi
wejsciowymi), ze przejmie kontrole nad Twoim komputerem.
Jednym z rozwiazan jest uzycie funkcji snprintf, ktora
oprocz adresu bufora pobiera informacje o jego dlugosci,
tak ze mozesz sobie napisac
snprintf(buffer, 256,
"mam sobie string `%s` o nieznanej dlugosci!", jakas_zmienna);
Jest to jednak rozwiazanie o tyle malo satysfakcjonujace,
ze wprawdzie bezpieczenstwo systemu wzrasta, ale wygenerowany
string moze zostac brzydko uciety (co zreszta moze powodowac
problemy innego rodzaju).
Z tego powodu standard GNU wprowadza funkcje asprintf,
o nastepujacej sygnaturze:
int asprintf(char **strp, const char *fmt, ...);
Jak widac, funkcja ta jako pierwszy argument pobiera
wskaznik na wskaznik na char. Idea jest taka, ze to
funkcja asprintf jest odpowiedzialna za to, zeby
zaalokowac odpowiednio duzy bufor. Dzieki temu mamy
pewnosc, ze wszystko bedzie dzialalo dobrze dopoty,
dopoki w komputerze jest dostepna dostateczna ilosc
pamieci. Jedyna upierdliwosc jest taka, ze musimy
sami pozniej zwolnic te pamiec. Czyli sposob uzycia
funkcji jest mniej wiecej nastepujacy:
char *buffer_pointer;
if(asprintf(&buffer_pointer, "jakis format", jakies zmienne ...) != -1) {
// pouzywaj sobie jakos wygenerowanego tekstu
// ...
// a na koncu zwolnij pamiec
free(buffer_pointer);
}
Analogiczny problem (i rowniez rozwiaznywany przy
pomocy wskaznikow na wskazniki) jest zwiazany z funkcja
[fs]?scanf.
Tutaj pozwole sobie przekleic przyklad z manuala:
/* scanf example */
#include <stdio.h>
int main ()
{
char str [80];
int i;
printf ("Enter your family name: ");
scanf ("%79s",str);
printf ("Enter your age: ");
scanf ("%d",&i);
printf ("Mr. %s , %d years old.\n",str,i);
printf ("Enter a hexadecimal number: ");
scanf ("%x",&i);
printf ("You have entered %#x (%d).\n",i,i);
return 0;
}
Jak widzimy, korzystamy ze specjalnego modyfikatora
dla metody %s, dzieki ktorej zapewniamy, ze wczytywany
tekst miesci sie w buforze. Gdyby nie bylo tej liczby,
79, to scanf w trakcie czytania moglby wyjechac poza
zakres bufora i znow nieprzyzwoicie namieszac.
Jednak co jesli nie chcemy dawac ograniczen na rozmiar
tekstu, ktory moze zostac wczytany? Tutaj znow z pomoca
przychodza rozszerzenia GNU.
Idea jest taka, ze zamiast adresu bufora przekazuje
wskaznik na zmienna, ktora bedzie miala przechowywac
adres nowozaalokowanego bufora:
char *buf = NULL;
scanf("%as", &buf);
Ponownie programista musi jednak zadbac o kontrole
bledow i o zwolnienie pamieci, gdy przestanie juz
byc potrzebna:
if(buf) {
// zrob cos z zawartoscia bufora
// ...
free(buf);
}
HTH
Następne wpisy z tego wątku
- 15.01.14 11:48 firr
- 15.01.14 12:05 firr
- 15.01.14 14:01 Adam Klobukowski
- 15.01.14 14:22 g...@g...com
- 15.01.14 14:49 Adam Klobukowski
- 15.01.14 15:09 Maciej Sobczak
- 15.01.14 15:17 Maciej Sobczak
- 15.01.14 16:24 A.L.
- 16.01.14 06:59 Adam Klobukowski
- 16.01.14 08:48 Andrzej Jarzabek
- 16.01.14 08:51 Andrzej Jarzabek
- 16.01.14 09:51 Maciej Sobczak
- 16.01.14 12:40 firr
- 17.01.14 01:24 A.L.
- 17.01.14 01:31 bartekltg
Najnowsze wątki z tej grupy
- A Szwajcarzy kombinują tak: FinalSpark grows human neurons from stem cells and connects them to electrode arrays
- Re: Najgorszy język programowania
- NOWY: 2025-09-29 Alg., Strukt. Danych i Tech. Prog. - komentarz.pdf
- Na grupie comp.os.linux.advocacy CrudeSausage twierdzi, że Micro$lop używa SI do szyfrowania formatu dok. XML
- Błąd w Sofcie Powodem Wymiany 3 Duńskich Fregat Typu Iver Huitfeldt
- Grok zaczął nadużywać wulgaryzmów i wprost obrażać niektóre znane osoby
- Can you activate BMW 48V 10Ah Li-Ion battery, connecting to CAN-USB laptop interface ?
- We Wrocławiu ruszyła Odra 5, pierwszy w Polsce komputer kwantowy z nadprzewodzącymi kubitami
- Ada-Europe - AEiC 2025 early registration deadline imminent
- John Carmack twierdzi, że gdyby gry były optymalizowane, to wystarczyły by stare kompy
- Ada-Europe Int.Conf. Reliable Software Technologies, AEiC 2025
- Linuks od wer. 6.15 przestanie wspierać procesory 486 i będzie wymagać min. Pentium
- ,,Polski przemysł jest w stanie agonalnym" - podkreślił dobitnie, wskazując na brak zamówień.
- Rewolucja w debugowaniu!!! SI analizuje zrzuty pamięci systemu M$ Windows!!!
- Brednie w wiki - hasło Dehomag
Najnowsze wątki
- 2025-12-26 Gdańsk => ERP Microsoft Dynamics 365 Commerce Consultant <=
- 2025-12-26 Kraków => Konsultant Microsoft Dynamics 365 Finance <=
- 2025-12-26 Kraków => Microsoft Dynamics 365 Finance Consultant <=
- 2025-12-26 wymieniłem termostat
- 2025-12-26 Warszawa => Senior Backend Java Developer <=
- 2025-12-25 Finlandia przywraca swastykę
- 2025-12-25 Skuteczność wymiaru sprawiedliwości
- 2025-12-24 Felgi
- 2025-12-24 2,5 x więcej niż Li-Ion
- 2025-12-24 No i kolejny ograniczony
- 2025-12-24 Warszawa => Młodszy Specjalista ds. wsparcia sprzedaży <=
- 2025-12-24 New York Times zagrożeniem bezpieczeństwa narodowego USA - POTUS D. Trump
- 2025-12-24 Podżeganie?
- 2025-12-24 => Senior Algorithm Developer (Java/Kotlin) <=
- 2025-12-24 otwarcie drugiej obwodnicy Trójmiasta




7 pułapek i okazji - zobacz co cię czeka podczas kupna mieszkania na wynajem