Как исправить ожидаемые спецификаторы объявления realloc или ошибку «…» перед ошибкой sizeof?
После звонка я получаю следующую ошибку ниже realloc
void* realloc(sizeof(char)100);
Ошибка:
linex.c: 23: 16: ошибка: ожидаемые спецификаторы объявления или '...' перед 'sizeof'
Пожалуйста помоги. Спасибо. :)
Ответы
void realloc(sizeof(char)100);
Предполагая, что вы имеете в виду вызов стандартной realloc()
функции (а не объявление кастомной функции realloc()
) и хотите изменить размер памяти, этот код неверен в отношении трех пунктов.
1.
realloc()
требуется указатель на память, выделенную управлением памятью и еще не освобожденную в качестве первого аргумента.
Это прототип / объявление стандартной realloc()
функции:
void *realloc( void *ptr, size_t new_size );
Ваш realloc()
вызов пропускает этот аргумент указателя.
2.
Не указывайте тип возврата (здесь void *
), когда вы хотите вызвать функцию. Таким образом вы пытаетесь сделать новое объявление функции, realloc()
а не вызов.
Если вы пытались сделать здесь кастинг, это тоже неправильно. Для неявного приведения необходимо заключить приводимый тип в круглые скобки, например (void *)
.
Обратите внимание, что в обоих случаях приведение является избыточным. Учитывая приведение возвращаемого типа, взгляните на:
- Могу ли я использовать результат malloc?
3.
В качестве аргумента размера вам понадобится *
оператор между sizeof(char)
и 100
.
Использование:
realloc( ptr, sizeof(char) * 100 );
Обратите внимание, что вы также всегда должны проверять возвращаемое значение функций управления памятью, произошла ли ошибка или нет:
char * ptr2 = realloc( ptr1, sizeof(char) * 100);
if ( ptr2 == NULL )
{
fputs("Error at resizing the allocated memory!\n", stderr);
// error routine.
}
То же самое вы всегда должны делать для malloc()
:
char * ptr1 = malloc( sizeof(char) * 50);
if ( ptr1 == NULL )
{
fputs("Error at memory allocation!\n", stderr);
// error routine.
}
Урок продвинутого уровня (на данном этапе вам не нужно его понимать):
Обратите внимание, что в случае realloc()
, я использую другой указатель для получения возвращаемого значения realloc()
.
Это потому, что realloc()
может или не может возвращать тот же указатель, переданный в качестве аргумента.
К сожалению, распространенная, но плохая практика - переназначить указатель, переданный в качестве первого аргумента, на возвращаемое значение realloc()
.
Это опасно, поскольку ссылка на память, выделенную первой, может быть потеряна, если realloc()
выделена другая «замещающая» память, но первая не стерта.
Связанный:
- Является ли хорошей практикой кодирования назначать адрес, возвращаемый realloc (), одному и тому же указателю?
- https://stackoverflow.com/a/25435175/12139179
- Как realloc () перераспределяет память?
void* realloc(sizeof(char)*100);
представляет собой мешанину объявления функции и ее вызова.
Когда мы объявляем функцию, мы говорим, какой у нее тип возвращаемого значения и какие типы у нее параметры, как в void *realloc(void *, size_t);
. Мы также можем предоставить имена-заполнители для параметров в качестве полезных описаний, например void *realloc(void *pointer, size_t size);
. (Имена параметров требуются при полном определении функции.)
Когда мы вызываем функцию, мы не указываем имена типов для возвращаемого значения или параметров. Мы просто даем выражения, которые предоставляют значения аргументов, как в NewPointer = realloc(OldPointer, 100 * sizeof *NewPointer);
.
Иногда имена типов могут появляться в вызове функции или рядом с ним, но они являются случайными и не являются непосредственно частью вызова функции. Примеры:
char *NewPointer = realloc(OldPointer, 100 * sizeof *NewPointer);
: Этот код имеет,char *
потому что он объявляет и определяетNewPointer
. ЗатемNewPointer
инициализируетсяrealloc
вызовом.NewPointer = (char *) realloc(OldPointer, 100 * sizeof *NewPointer);
: Этот код имеет(char *)
приведение для преобразования возвращаемого значенияrealloc
в определенный тип указателя. Это не требуется в C.NewPointer = realloc(OldPointer, 100 * sizeof(char));
: Этот код имеетchar *
в качестве операндаsizeof
для вычисления необходимого пространства. В этом нет необходимости, потому что размер может быть взят сsizeof *NewPointer
, и это обычно предпочтительнее, потому что он автоматически подстраивается под изменения в объявленииNewPointer
, уменьшая вероятность того, что ошибка может быть внесена путем изменения типа в объявлении,NewPointer
но игнорированияsizeof
выражения.