#c #memory-management
#c #управление памятью
Вопрос:
Я пытаюсь создать программу счетчика слов, которая принимает предложение и подсчитывает количество слов. Я хотел бы использовать динамическое выделение памяти, потому что оно имеет много преимуществ, таких как отсутствие необходимости беспокоиться о нехватке места или слишком большом количестве пустого пространства. Вот мой код до сих пор:
#include <stdio.h>
#include <stdlib.h>
const char *strmalloc(const char *string);
char *user_input = NULL;
int main(void) {
printf("Enter a sentence to find out the number of words: ");
strmalloc(user_input);
return 0;
}
const char *strmalloc(const char *string) {
char *tmp = NULL;
size_t size = 0, index = 0;
int ch;
while ((ch = getchar()) != 'n' amp;amp; ch != EOF) {
if (size <= index) {
size = 1;
tmp = realloc((char*)string, size);
}
}
}
Как вы, возможно, знаете, прототип функции realloc выглядит следующим образом:
void *realloc(void *ptr, size_t size)
Когда я использую функцию realloc в цикле while в strmalloc()
функции, я получаю предупреждение о том, что:
Passing 'const char *' to parameter of type 'void *' discards qualifiers
Я понятия не имею, что это значит, но я знаю, что могу избавиться от этого с помощью приведения типов к char*
Однако я узнал, что я не должен использовать приведение типов только для предотвращения предупреждения. Я должен узнать, о чем предупреждает меня предупреждение, и решить, является ли приведение типов правильным. Но опять же, я знаю, что указатель на void принимает любой тип данных, и для его указания требуется приведение типов. Итак, мой вопрос в том, должен ли я сохранить типизацию в realloc()
функции или избавиться от нее и сделать что-то еще.
Комментарии:
1. Квалификатор — это ключевое слово, такое как
volatile
илиconst
, которое изменяет тип. Это помогает?2. @JohnKugelman Спасибо, что ответили на эту часть вопроса, но у меня все еще есть главный вопрос без ответа. Если вы знаете ответ, пожалуйста, скажите мне. Спасибо!
3. Это приведет вас к правильному ответу. Вы правы, что хотите избежать удаления предупреждения. Есть лучшее решение, чем отбрасывание
const
.4. @JohnKugelman, извините, я не думаю, что понимаю. Не могли бы вы сказать мне, к чему вы клоните?
5. Не отбрасывайте квалификацию const .
remove_spaces
Пример очень похож на ваш код.
Ответ №1:
const
является определителем типа. В C
и, возможно, во многих других языках программирования, const
примененный к типу данных, указывает, что данные доступны только для чтения.
Передача ‘const char *’ в параметр типа ‘void *’ отбрасывает квалификаторы
Приведенная выше ошибка, которую вы получаете, потому что вы передаете const
object параметру, которого нет const
( (void *)
in realloc
), и предупреждаете вас о возможности изменения (отбрасывания) значений, указанных const char* string
с помощью void* ptr
, что сводит на нет всю цель объявления данных как const
.
Но, глядя на пример, вы пытаетесь выделить память для char* string
, и после выделения вы хотели бы что-то записать в эту память, если вы это сделаете const
, как вы ожидаете, что она будет записана.
Таким образом, вам не нужно, чтобы вы char* string
были const
, и, следовательно, нет необходимости в приведении к char*
in realloc
.
Комментарии:
1. Спасибо @IrAM, вы правы в том, что не можете изменить
const char *string
значение. Я не знал, о чем я думал. Но спасибо!