>> 1 głośnik: Napiszmy program, który Pobiera ciąg od użytkownika bez
używając CS50 biblioteki funkcjonować GetString.
Aby to zrobić, będziemy już używać scanf, funkcja GetString
funkcja nie używa pod wyciągiem.
Ale mam zamiar to zrobić celowo w sposób buggy.
Mam zamiar zrobić w taki sposób, że myślę, że byłoby dobrze, ale okazuje się, że
moje założenie będzie całkiem, całkiem błędna.
I rzeczywiście bardzo niebezpieczne.
Ponieważ błędy takie jak ten mam zamiar Marka może być wykorzystana przez przeciwników
takie, że urządzenie lub program może zostać przejęte potencjalnie.
>> Zacznijmy w następujący sposób.
Zacznijmy deklarujemy ciąg, znanym teraz jako gwiazda char,
i nazywają to s.
Pozwala obok pyta użytkownika o ciąg, jak z "ciąg proszę." I
niech teraz uzyskać ciąg od użytkownika przy użyciu scanf, cytatu, "% s". W
Innymi słowy, załóżmy, że my informujemy scanf Czy rzeczywiście spodziewać się ciąg
od użytkownika.
>> Ale teraz musimy powiedzieć scanf jedna rzecz -
gdzie umieścić napis, że Użytkownik zapewnia.
Cóż, mam zamiar po prostu zacząć z przecinkiem s, określając, że chciałbym
scanf umieścić ciąg tam.
Jestem następny zamiar wydrukować coś jak printf "thanks for% s
odwrotny ukośnik n przecinek. "I jak zawsze, jestem przejdzie w ciągu, s..
Teraz możemy zapisać, skompilować i uruchomić ten Program, i zobacz, czy nie możemy wywoływać
Problem przewidziałem.
>> Dodać scanf-1.
./scanf-1.
Ciąg proszę.
Miejmy dostarczyć coś, "hello". "Dzięki za null." Hmm, to nie jest
czego się spodziewałem.
Więc co tu się dzieje?
>> Cóż, okazuje się, dlatego, że zadeklarowane a jako gwiazda char ale nie
faktycznie przechowywane w s adres Rzeczywisty fragment pamięci, scanf nie
nigdzie umieścić napis że użytkownik wpisze w.
W rzeczywistości, jeżeli użytkownik był do tej pory wpisać znacznie dłuższy ciąg niż "hello"
na przykład kilka linii tekstu lub kilka akapitów tekstu, jest dość
możliwe, że możemy wywołać tzw błędu segmentacji.
>> Bo scanf nie będzie wiedzieć, że Nie faktycznie umieścić adres
wewnątrz s.
Raczej to się zobaczyć jakąś wartość w s, jakiś wzór bitów, które mogą
bardzo dobrze wartość śmieci, nie tylko przez przypadek.
I scanf nadal będzie starał się pisać Ciąg użytkownikowi tego adresu,
Nawet jeśli jest to wartość śmieci, które rzeczywiście może wywołać katastrofę.
>> Więc jak będziemy to naprawić?