2012-10-24 9 views
7

Czy są jakieś pułapki podczas używania znaków char * do pisania kodu wieloplatformowego, który zapewnia dostęp do pamięci?Jakieś pułapki używające char * zamiast void * podczas pisania kodu cross-platform?

AKTUALIZACJA: Na przykład, czy powinienem sprawdzić przed przesłaniem dereferencji char * do określonego typu (np. Int), jeśli adres jest wyrównany do rozmiaru tego typu? Czy niektóre architektury zwrócą dziwne wyniki w przypadku braku dostępu?

Pracuję nad podzielnikiem pamięci odtwarzania, aby lepiej zrozumieć, jak debugować problemy z pamięcią. Doszedłem do wniosku, że char * są lepsze ze względu na umiejętność robienia arytmetyki wskaźnikowej i dereferencji nad pustką *, czy to prawda? Czy następujące założenia są zawsze prawdziwe na różnych typowych platformach?

sizeof(char) == 1 
sizeof(char*) == sizeof(void*) 
sizeof(char*) == sizeof(size_t) 
+0

Jeśli nie usuniesz zabezpieczeń z instancji char, będziesz musiał rzucić zarówno "char *" i "void *" do dowolnego typu, na który wskazują. – Aesthete

+0

Nie wiem, czy jest to "gwarantowane", ale z mojego doświadczenia pierwsze 2 powinny być bezpieczne. Ostatni...??. – vdbuilder

Odpowiedz

5

sizeof(char)==1 jest zdecydowanie zawsze prawdziwe.

to prawdopodobnie zawsze również prawdziwe. Norma C wymaga, aby miały tę samą reprezentację, która co najmniej silnie implikuje ten sam rozmiar.

sizeof(char *) == sizeof(size_t) zdecydowanie nie można na nie polegać - znam implementacje, dla których jest ona nieprawdziwa (i chociaż prawdopodobnie nie są zgodne ze standardem, to nie jest to jeden z ich problemów).

+1

Dzięki Jerry. Czy znasz typ, który zawsze ma taki sam rozmiar jak rozmiar wskaźnika (inny niż typ wskaźnika :))? Na przykład powinno to być 32 bity na 32-bitowej kompilacji i 64 na 64-bitowej. Byłem pod wrażeniem size_t było tego typu. – UberMongoose

+1

@UberMongoose: po pierwsze, nie ma wymogu, aby wszystkie wskaźniki miały ten sam rozmiar. Zwykle będą, ale nie jest to wymagane. W większości typowych sytuacji wielkość 'size_t' będzie taka sama, ale znowu nie jest gwarantowana (i znam przynajmniej kilka wyjątków). MS (na przykład) definiuje niektóre typy, takie jak INT_PTR (liczba całkowita o takim samym rozmiarze jak wskaźnik), ale to daleki od uniwersalności. Prawdopodobnie najlepsze, co możesz zrobić, to użyć typedef w nagłówku konfiguracji, abyś mógł modyfikować, jeśli trafisz na platformę, na której musisz. –

+2

intptr_t? "Poniższy typ oznacza typ liczby ze znakiem z tą właściwością, że dowolny prawidłowy wskaźnik do unieważnienia może zostać przekonwertowany na ten typ, a następnie przekonwertowany z powrotem na wskaźnik, aby unieważnić, a wynik będzie porównywany z oryginalnym wskaźnikiem" – rici