-
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
- 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
- Perfidne ataki krakerów z KRLD na skrypciarzy JS i Pajton
- Instytut IDEAS może zacząć działać: "Ma to być unikalny w europejskiej skali ośrodek badań nad sztuczną inteligencją."
- Instytut IDEAS może zacząć działać: "Ma to być unikalny w europejskiej skali ośrodek badań nad sztuczną inteligencją."
Najnowsze wątki
- 2025-08-06 Gdynia => Konsultant wdrożeniowy (systemy controlingowe) <=
- 2025-08-06 Białystok => Inżynier oprogramowania .Net <=
- 2025-08-06 "[...] sejmowe wystąpienie posłanki Klaudii Jachiry, która zakończyła je słowami ,,Sława Ukrainie"."
- 2025-08-05 "Chiny przekraczają w wydobyciu 4 mld ton węgla, Indie i USA ponad 1 mld, a Rosja 500 mln ton [...]"
- 2025-08-05 Panuje się 181 159,42 zł./mies. na posła w 2026r.
- 2025-08-05 "Chiny przekraczają w wydobyciu 4 mld ton węgla, Indie i USA ponad 1 mld, a Rosja 500 mln ton [...]"
- 2025-08-05 Czy cos fi przechodzi przez trafo separujące?
- 2025-08-05 kajaki i promile
- 2025-08-05 Re: Tesla jest bezpieczna, wczoraj spaliła się doszczętnie na Ursynowie i nikomu się nic nie stało
- 2025-08-05 Gdynia => Przedstawiciel handlowy / KAM (branża TSL) <=
- 2025-08-05 Re: Atak na lekarza w Oławie. Policja zatrzymała sprawcę na lotnisku Polska Agencja Prasowa 4 sierpnia 2025, 12:16 FACEBOOK X E-MAIL KOPIUJ LINK W szpitalu w Oławie 37-letni pacjent zaatakował lekarza, po tym, jak ten odmówił mu wypisania długoterminowego
- 2025-08-05 B2B i książka przychodów i rozchodów
- 2025-08-04 Re: Atak na lekarza w Oławie. Policja zatrzymała sprawcę na lotnisku Polska Agencja Prasowa 4 sierpnia 2025, 12:16 FACEBOOK X E-MAIL KOPIUJ LINK W szpitalu w Oławie 37-letni pacjent zaatakował lekarza, po tym, jak ten odmówił mu wypisania długoterminowego
- 2025-08-04 Na grupie comp.os.linux.advocacy CrudeSausage twierdzi, że Micro$lop używa SI do szyfrowania formatu dok. XML
- 2025-08-04 Na grupie comp.os.linux.advocacy CrudeSausage twierdzi, że Micro$lop używa SI do szyfrowania formatu dok. XML