Jak naprawić ponowne przydzielenie oczekiwanych specyfikatorów deklaracji lub błąd „…” przed „sizeof”?

Aug 15 2020

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

1 RobertSsupportsMonicaCellio Aug 15 2020 at 15:42
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ęć?
1 EricPostpischil Aug 15 2020 at 17:35

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 definiuje NewPointer. Następnie NewPointerjest inicjowany reallocwywołaniem.
  • NewPointer = (char *) realloc(OldPointer, 100 * sizeof *NewPointer);: Ten kod ma (char *)jako rzutowanie do konwersji wartości zwracanej reallocna określony typ wskaźnika. Nie jest to potrzebne w C.
  • NewPointer = realloc(OldPointer, 100 * sizeof(char));: Ten kod ma char *jako operand sizeofdo obliczenia potrzebnej przestrzeni. Jest to niepotrzebne, ponieważ można wziąć rozmiar z sizeof *NewPointer, i jest to ogólnie preferowane, ponieważ automatycznie dostosowuje się do zmian w deklaracji NewPointer, zmniejszając możliwość wprowadzenia błędu przez zmianę typu w deklaracji, NewPointerale przeoczenie sizeofwyrażenia.