2010-07-09 9 views
5

W programowaniu C, gdy próbuję wykonać pierwszy czas kota, muszęUstaw pierwszy bajt 0 lub użyć memset na „reset” cały bufor

TCHAR file_name[1024]; 
// Use memset or set the first byte to 0? 
file_name[0] = 0; 
_tcscat(file_name, TEMP_DIRECTORY_PATH); 
_tcscat(file_name, file); 

widzę większość programistów korzysta memset. Ale dla mnie ustawiłem pierwszy bajt na 0, aby umożliwić _tcscat wie, od czego zacząć.

Nie jestem pewien, czy jest jakaś pułapka/pułapka, zamiast używać memsetu?

Dzięki.

Odpowiedz

3

Ty może prostu ustawić pierwszy char do 0.

jednak jeszcze prostszy sposób byłoby

TCHAR file_name[1024]; 
_tcsncpy(file_name, TEMP_DIRECTORY_PATH, 1024); 
_tcscat(file_name, file); 
1

Nic tak naprawdę, poza tym ustawienie wszystkiego na zero może zapobiec błędom później, to znaczy, jeśli z jakiegoś powodu nie doda się błędów. Łatwiej jest wypełnić cały ciąg zerami i wiedzieć, że nie musisz się martwić o dodanie terminatora o wartości null ręcznie później, dopóki nie przepełnisz bufora.

+0

Nie zgadzam się. Bardziej prawdopodobne jest ukrywanie błędów w logice, która nagle pojawi się, gdy ktoś utrzymujący kod później zdecyduje "hej, usuńmy wszystkie te niepotrzebne memy!" –

1

Ustawienie całego bufora na znaki NUL to "obrona w głębi". Taka obrona obejmuje błąd popełniony gdzie indziej w kodzie źródłowym, być może przez innego programistę. W tym przypadku pomijany błąd polegałby na skopiowaniu ciągu pasującego do bufora, ale nie skopiowaniu bajtu kończącego NUL. Bufor już-zerowy zapewniłby zakończenie NUL-ów dla tej błędnej kopii napisów do "użycia". Programiści różnią się mądrością "Obrona w głębokości", ponieważ takie kodowanie może maskować błędy programistyczne, które mogą następnie ulegać zahartowaniu w kodzie źródłowym - naprawiane tylko długo po ich wprowadzeniu.

W mojej osobistej opinii ustawienie bufora dla wszystkich postaci NUL, takich jak ta, jako "obrona w głębi" jest ogromnym marnotrawstwem. Bardziej sensowny byłby tylko NUL, ostatni bajt. Następnie pojawiłyby się błędy, ale ciągi zostałyby ostatecznie zakończone. Gdy zaczniesz iść tą ścieżką myśli, "obrona w głąb" będzie miała więcej sensu, jeśli bufor zostanie uczyniony dwoma słowami maszynowymi dłuższymi, a te słowa były wyzerowane, a możliwa wartość kanarka mogłaby zgłosić przekroczenie bufor i ...

Albo możesz po prostu nie przekroczyć buforów i napisać swój program tak, aby załamał się tak szybko, jak to możliwe, jeśli to zrobisz. To właśnie lubię robić.

+0

+1 dla ładnej analizy plusów i minusów różnych opcji –

4

Nie zgadzam się z większości odpowiedzi, które wydają się wskazywać, że umieszczenie całego bufor na 0 może być pomocny. Jeśli kopiujesz/łączę łańcuchy zakończone znakiem NUL do bufora, nie ma potrzeby, aby oczyścić całość - wydaje mi się, że jest to marnotrawstwo (choć z pewnością może to być marnotrawstwo, którego nie warto martwić się).

Można przyjąć podejście Artelius suggested i użyć wariantu strcpy() dostać początkowy ciąg do bufora, ale myślę, że symetria swoim podejściu stosując strcat() `ma zasługi, jak również (choć myślę, że po prostu ustawienie pierwszy znak to 0).

Na marginesie, jeśli bufor może zawierać dane "sensitve" (informacje o haśle lub coś w tym stylu) - może to być powodem do usunięcia całego problemu. Ale jeśli tak jest, spójrz na http://msdn.microsoft.com/en-us/library/ms972826 z kilku powodów, dla których memset() może nie wystarczyć.

+0

Naprawdę? Myślę, że to całkiem głupie, aby ustawić bufor na zera, ale myślę, że nie natknąłem się w mojej odpowiedzi –

+0

I cokolwiek robisz zero bezpiecznej pamięci, nie przechowuj jej w chronionej pamięci Microsoft ... To oczywiście jest kompatybilne z CALEA, wybierzcie chyba swoją stronę, –

+0

Jeśli chcecie symetrii, możecie użyć 'strcpy (s," "); ', aby" zainicjować "ciąg znaków i nadal używać' strcat' dla wszystkich prawidłowych zapisów. –