Jak naprawić ponowne przydzielenie oczekiwanych specyfikatorów deklaracji lub błąd „…” przed „sizeof”?
Po wywołaniu pojawia się następujący błąd realloc
void* realloc(sizeof(char)100);
Błąd:
linex.c: 23: 16: error: oczekiwane specyfikatory deklaracji lub '...' przed 'sizeof'
Proszę pomóż. Dziękuję Ci. :)
Odpowiedzi
void realloc(sizeof(char)100);
Zakładając, że masz na myśli wywołanie realloc()
funkcji standardowej (a nie deklarację niestandardową realloc()
) i chcesz zmienić rozmiar pamięci, ten kod jest błędny w trzech punktach.
1.
realloc()
potrzebuje wskaźnika do pamięci przydzielonej przez zarządzanie pamięcią i nie jest już zwolniona jako pierwszy argument.
Oto prototyp / deklaracja realloc()
funkcji standardowej :
void *realloc( void *ptr, size_t new_size );
Twoje realloc()
wywołanie pomija ten argument wskaźnika.
2.
Nie określaj typu zwracanego (tutaj void *
), gdy chcesz wywołać funkcję. W ten sposób próbujesz dokonać nowej deklaracji funkcji, realloc()
a nie wywołania.
Jeśli próbowałeś wykonać tutaj casting, to również jest złe. W przypadku niejawnego rzutowania należy otoczyć typ, na który ma być rzutowany, nawiasami, takimi jak (void *)
.
Zauważ, że w obu przypadkach obsada jest zbędna. Mając na uwadze rzut typu zwracanego, spójrz na:
- Czy mogę rzucić wynik malloc?
3.
W argumencie size potrzebujesz *
operatora między sizeof(char)
a 100
.
Posługiwać się:
realloc( ptr, sizeof(char) * 100 );
Zauważ, że zawsze powinieneś również sprawdzić wartość zwracaną przez funkcje zarządzania pamięcią, czy wystąpił błąd, czy nie:
char * ptr2 = realloc( ptr1, sizeof(char) * 100);
if ( ptr2 == NULL )
{
fputs("Error at resizing the allocated memory!\n", stderr);
// error routine.
}
To samo, co zawsze powinieneś robić dla malloc()
:
char * ptr1 = malloc( sizeof(char) * 50);
if ( ptr1 == NULL )
{
fputs("Error at memory allocation!\n", stderr);
// error routine.
}
Lekcja zaawansowana (nie musisz jej rozumieć w tym momencie):
Zauważ, że w przypadku realloc()
, używam innego wskaźnika, aby złapać wartość zwracaną przez realloc()
.
Dzieje się tak, ponieważ realloc()
może, ale nie musi, zwrócić ten sam wskaźnik przekazany jako argument.
Niestety, powszechną, ale złą praktyką jest ponowne przypisanie wskaźnika przekazanego jako pierwszy argument przez wartość zwracaną przez realloc()
.
Jest to niebezpieczne, ponieważ odniesienie do pamięci przydzielonej jako pierwsze może zostać utracone, jeśli realloc()
przydzielono inną pamięć „zastępczą”, ale nie skasowano pierwszej.
Związane z:
- Czy dobrą praktyką kodowania jest przypisanie adresu zwróconego przez realloc () do tego samego wskaźnika?
- https://stackoverflow.com/a/25435175/12139179
- W jaki sposób funkcja realloc () ponownie przydziela pamięć?
void* realloc(sizeof(char)*100);
jest miszmaszem deklarowania funkcji i wywoływania jej.
Kiedy deklarujemy funkcję, mówimy, jaki jest jej typ zwracany i jakie typy są jej parametry, tak jak w void *realloc(void *, size_t);
. Możemy również podać nazwy symboli zastępczych dla parametrów jako pomocne opisy, jak w void *realloc(void *pointer, size_t size);
. (Nazwy parametrów są wymagane podczas pełnego definiowania funkcji).
Kiedy wywołujemy funkcję, nie podajemy nazw typów dla zwracanej wartości ani parametrów. Po prostu podajemy wyrażenia, które dostarczają wartości argumentów, jak w NewPointer = realloc(OldPointer, 100 * sizeof *NewPointer);
.
Czasami nazwy typów mogą pojawiać się w wywołaniu funkcji lub w jego pobliżu, ale są one przypadkowe i nie są bezpośrednio częścią wywołania funkcji. Przykłady:
char *NewPointer = realloc(OldPointer, 100 * sizeof *NewPointer);
: Ten kod ma,char *
ponieważ deklaruje i definiujeNewPointer
. NastępnieNewPointer
jest inicjowanyrealloc
wywołaniem.NewPointer = (char *) realloc(OldPointer, 100 * sizeof *NewPointer);
: Ten kod ma(char *)
jako rzutowanie do konwersji wartości zwracanejrealloc
na określony typ wskaźnika. Nie jest to potrzebne w C.NewPointer = realloc(OldPointer, 100 * sizeof(char));
: Ten kod machar *
jako operandsizeof
do obliczenia potrzebnej przestrzeni. Jest to niepotrzebne, ponieważ można wziąć rozmiar zsizeof *NewPointer
, i jest to ogólnie preferowane, ponieważ automatycznie dostosowuje się do zmian w deklaracjiNewPointer
, zmniejszając możliwość wprowadzenia błędu przez zmianę typu w deklaracji,NewPointer
ale przeoczeniesizeof
wyrażenia.