czytałem nowy (maj 2013), O'Reilly książki „zrozumieniu i wykorzystaniu C Wskaźniki” Richard Reese, i mam pytanie dotyczące jakiegoś kodu w nim, na stronie 87.Używanie oryginalnego wskaźnika po ponownym przydziale?
if (++length > maximumLength) {
char *newBuffer = realloc (buffer, maximumLength += sizeIncrement);
if (newBuffer == NULL) {
free (buffer);
return NULL;
}
currentPosition = newBuffer + (currentPosition - buffer);
buffer = newBuffer;
}
Mam nadzieję nazwy zmienne są oczywiste; jeśli potrzebny jest kontekst, będę edytować, aby dostarczyć cały fragment kodu, a nie tylko ten fragment.
Moje pytanie dotyczy linii currentPosition = newBuffer + (currentPosition - buffer);
. Moje rozumienie realloc()
jest takie, że gdy nowa alokacja się powiedzie, pierwotnie przydzielona pamięć zostanie zwolniona. Jeśli to prawda, to linia, o której mowa, używa wskaźników zwisających, innit? Zarówno buffer
, jak i currentPosition
na RHS tego wyrażenia są wskaźnikami do pamięci, która została zwolniona.
Moim instynktem byłoby przepisanie tego, aby uniknąć używania zwisających wskaźników za pomocą length
, który przecież już jest w pobliżu. Chcę zastąpić te dwie ostatnie linie z:
buffer = newBuffer;
currentPosition = buffer + length;
Niemniej jednak przypuszczalnie kod jako prac pisemnych, ponieważ oba wskaźniki nadal posiadają adresy (aczkolwiek śmieci), a przesunięcie między tymi dwoma adresami można jeszcze obliczony jako sposób zmiany przydziału currentPosition
. Czy jestem po prostu personicką w tym, że czuję się z tym nieswojo?
Aby uogólnić pytanie: gdy wskaźnik jest zwisający, czy można bezpiecznie używać adresu zawartego w wskaźniku w dowolnym celu, na przykład do obliczania przesunięć? Dzięki.
W czasie realokacji "długość" jest o jeden większa od wielkości bufora ("maksymalna długość" przed korektą). Powinieneś używać 'currentPosition = buffer + length - 1', jeśli poprawnie interpretuję znaczenia. – Casey
Sprawdziłem to przed faktycznym opublikowaniem pytania. Kod książki inicjalizuje zarówno "długość" jak i "aktualną pozycję" do zera. "length" jest inkrementowane w pierwszym warunkowym, więc zawsze jest o jeden za indeksem ostatnio dodanego elementu. 'currentPosition' to miejsce, w którym nowy element ma zostać dodany, a po dodaniu zwiększa się. Nie tak powinienem napisać kod na początek, ale biorąc podany kod, 'buffer + length' jest poprawny. – verbose
Więc 'currentPosition' to wstępnie skomponowany' buffer + length'? Stoję poprawiony (i lekko zaskoczony przez redundancję). – Casey