2010-10-29 13 views
17
const char* a; 

Jak mogę się upewnić, że ciąg "a" jest zakończony znakiem null? kiedy a = "abcd" i robię sizeof (a), otrzymuję 4. Czy to oznacza, że ​​nie jest on zakończony znakiem null? gdyby tak było, dostałbym 5?sizeof dla zakończonej znakiem zero const char *

Odpowiedz

5

Jeśli dostaniesz tablicę znaków, która może zawierać lub nie ma danych zakończonych znakiem NUL, naprawdę nie jest dobrym sposobem sprawdzenia. Najlepsze, co możesz zrobić, to szukać znaku pustego aż do określonej wartości cedera (nie w nieskończoność!). Ale 0 nie jest dokładnie niezwykłym bajtem danych, które można znaleźć w niezainicjowanym obszarze pamięci.

Jest to jedna z wielu cech standardu C defacto, którego nie lubi wiele osób. Odnalezienie długości ciągu, który klient podaje użytkownikowi, to operacja wyszukiwania O (n) w najlepszym wypadku, aw najgorszym przypadku błąd segmentacji.

Inną kwestią jest oczywiście, że tablice i wskaźniki są wymienialne.Oznacza to, że array_name + 2 jest taki sam jak &(array_name[2]) i sizeof(a) jest sizeof(char*), a nie długość tablicy.

11

Otrzymujesz 4, ponieważ jest to wielkość wskaźnika w twoim systemie. Jeśli chcesz uzyskać długość łańcucha zakończonego nul, potrzebujesz funkcji strlen w standardowej bibliotece C.

+0

'strnlen' dla bezpieczeństwa. – nmichaels

+0

'Strnlen' jest specyficzny dla platformy, a nie w standardzie. – jer

+6

@Nathon: 'strnlen' tak naprawdę nie zwiększa bezpieczeństwa, prawda? Jeśli twoja funkcja wymaga łańcucha zakończonego wartością NULL i nie dostaje jednego (lub jeśli funkcja jest określona jako zwracająca łańcuch zakończony znakiem NUL i nie zwraca żadnej), twój kod jest już uszkodzony. –

28

podaje rozmiar wskaźnika, a nie tablicy znaków wskazywanej przez wskaźnik. To tak samo, jakbyś powiedział: sizeof(char*).

Trzeba użyć strlen() obliczyć długość łańcucha nul (należy pamiętać, że długość powrócił nie obejmują null terminator, więc strlen("abcd") wynosi 4, a nie 5). Albo można zainicjować tablicę z ciągiem dosłownym:

char a[] = "abcd"; 
size_t sizeof_a = sizeof(a); // sizeof_a is 5, because 'a' is an array not a pointer 

Ciąg dosłowne "abcd" jest zerowa zakończone; wszystkie ciągi literałów mają wartość NUL zakończoną.

+1

OP już używało 'const', więc' const char a [] 'jest prawdopodobnie lepszym pomysłem niż' char a [] '. – aschepler

+4

Aby dokładniej wyjaśnić, 'strlen()' poda logiczną prawdę danych w tablicy char, a nie liczbę bajtów dla niej przydzielonych. Nie sądzę, że istnieje sposób na zdobycie tego numeru. –

4

sizeof(a) to sizeof(const char*), wielkość wskaźnika. Nie ma na nią wpływu zawartość a. Do tego chcesz strlen.

Również wszystkie cudzysłowy ciągów o podwójnym cudzysłowiu, takie jak Twój "abcd" w kodzie źródłowym, są automatycznie zerowane.

1

sizeof (a) zwraca rozmiar const char *a ... nie rozmiar tego, co wskazuje. Możesz użyć strlen(a), aby określić długość łańcucha zakończonego znakiem NUL, a nie, wynik strlen nie zawiera terminatora o wartości NULL.

6

Problem polega na tym, że wprowadzasz w błąd sizeof(), który jest operacją czasu kompilacji z długością łańcucha, który jest operacją wykonawczą. Powodem powrotu do stanu 4 po uruchomieniu sizeof(a) jest to, że a jest wskaźnikiem a typ wielkości wielkości wskaźnika C wynosi 4 bajty. Aby uzyskać długość ciągu, użyj strlen.

Aby uzyskać drugie pytanie, jak upewnić się, że ciąg znaków jest zakończony znakiem null. Jedynym sposobem, aby to ostatecznie zrobić, jest zerowanie samego ciągu. Biorąc pod uwagę tylko char*, nie ma sposobu, aby w 100% zagwarantować, że zostanie poprawnie zakończone. Należy zachować ostrożność, aby upewnić się, że umowa między producentem a konsumentem char* jest zrozumiała, kto kończy łańcuch.

+0

aah .... głupi mnie. Ale kiedy robię strlen (a) otrzymuję 4, i wiem, że ma "abcd" (z gdb). – hari

+0

@hari, 4 jest poprawny, ponieważ długość ciągu "abcd" jest rzeczywiście 4. Jednak wymagania pamięci dla 'a' to' strlen (a) + 1' do obsługi terminatora zerowego. To jedna z części C, która po prostu trochę się przyzwyczaja. – JaredPar

+0

To dlatego, że długość "abcd" wynosi 4. strlen nie liczy się z zakończeniem zerowym. – jer

Powiązane problemy