-
X-Received: by 10.49.117.170 with SMTP id kf10mr981qeb.36.1389781159904; Wed, 15 Jan
2014 02:19:19 -0800 (PST)
X-Received: by 10.49.117.170 with SMTP id kf10mr981qeb.36.1389781159904; Wed, 15 Jan
2014 02:19:19 -0800 (PST)
Path: news-archive.icm.edu.pl!agh.edu.pl!news.agh.edu.pl!news.cyf-kr.edu.pl!news.nask
.pl!news.nask.org.pl!news.unit0.net!news.glorb.com!6no11345233qao.1!news-out.go
ogle.com!gg4ni4085qab.0!nntp.google.com!6no11345229qao.1!postnews.google.com!gl
egroupsg2000goo.googlegroups.com!not-for-mail
Newsgroups: pl.comp.programming
Date: Wed, 15 Jan 2014 02:19:19 -0800 (PST)
In-Reply-To: <lb5jt7$mlv$1@node1.news.atman.pl>
Complaints-To: g...@g...com
Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=89.67.189.218;
posting-account=f7iIKQoAAAAkDKpUafc-4IXhmRAzdB5r
NNTP-Posting-Host: 89.67.189.218
References: <lb0plj$jfj$1@node2.news.atman.pl>
<1...@g...com>
<lb0rbd$l6n$1@node2.news.atman.pl>
<7...@g...com>
<lb0sk5$mgl$1@node2.news.atman.pl>
<b...@g...com>
<lb3o9l$ir1$1@node2.news.atman.pl>
<9...@g...com>
<lb3pl8$k6t$1@node2.news.atman.pl>
<9...@g...com>
<lb3ta8$o6m$1@node2.news.atman.pl> <lb3tke$oje$1@node2.news.atman.pl>
<52d57fb0$0$2356$65785112@news.neostrada.pl>
<a...@g...com>
<52d5abae$0$2147$65785112@news.neostrada.pl>
<3...@g...com>
<lb5jt7$mlv$1@node1.news.atman.pl>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <f...@g...com>
Subject: Re: pryszcze...
From: g...@g...com
Injection-Date: Wed, 15 Jan 2014 10:19:19 +0000
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
Xref: news-archive.icm.edu.pl pl.comp.programming:204932
[ ukryj 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
- Alg. kompresji LZW
- Popr. 14. Nauka i Praca Programisty C++ w III Rzeczy (pospolitej)
- Arch. Prog. Nieuprzywilejowanych w pełnej wer. na nowej s. WWW energokod.pl
- 7. Raport Totaliztyczny: Sprawa Qt Group wer. 424
- TCL - problem z escape ostatniego \ w nawiasach {}
- Nauka i Praca Programisty C++ w III Rzeczy (pospolitej)
- testy-wyd-sort - Podsumowanie
- Tworzenie Programów Nieuprzywilejowanych Opartych Na Wtyczkach
- Do czego nadaje się QDockWidget z bibl. Qt?
- Bibl. Qt jest sztucznie ograniczona - jest nieprzydatna do celów komercyjnych
- Co sciaga kretynow
- AEiC 2024 - Ada-Europe conference - Deadlines Approaching
- Jakie są dobre zasady programowania programów opartych na wtyczkach?
- sprawdzanie słów kluczowych dot. zła
- Re: W czym sie teraz pisze programy??
Najnowsze wątki
- 2025-02-21 Warszawa => Key Account Manager IT <=
- 2025-02-21 Warszawa => Data Engineer (Tech Lead) <=
- 2025-02-21 Aliexpress zaczął oszukiwać na bezczelnego.
- 2025-02-21 Warszawa => System Architect (Java background) <=
- 2025-02-21 Kula w łeb
- 2025-02-21 Warszawa => System Architect (background deweloperski w Java) <=
- 2025-02-21 Warszawa => Solution Architect (Java background) <=
- 2025-02-21 Lublin => JavaScript / Node / Fullstack Developer <=
- 2025-02-21 Pawel S
- 2025-02-21 Warszawa => Key Account Manager (Usługi HR) <=
- 2025-02-21 Katowice => Senior Field Sales (system ERP) <=
- 2025-02-21 Chrzanów => Programista NodeJS <=
- 2025-02-21 Wrocław => Konsultant wdrożeniowy Comarch XL/Optima (Księgowość i
- 2025-02-21 Warszawa => Administrator Systemów Windows IT <=
- 2025-02-21 Wrocław => Specjalista ds. Sprzedaży (transport drogowy) <=