Функция Realloc не изменяет размер

Эта функция должна читать и расширять мой массив (stringa) до тех пор, пока пользователь не нажмет Enter, а затем также расширяет reverse до того же размера, что и stringa. Но у меня две основные проблемы:

  1. после 3 букв программа просто останавливается (думаю это из-за пункта номер 2, но я не уверен)
  2. Я вставил printf("%d\n", sizeof(*stringa) / sizeof(*stringa[0])), чтобы проверить, меняется ли размер stringa, но, видимо, это не так (он печатает только 8)
void inputStringaAndCreateReverse(char* *stringa, char* *reverse, int* iStringa) {
    int inputChar, i = 0, size = 1;
    bool notEnter = true;
    printf("Insert the string: ");
    while (notEnter) {
        if ((inputChar = getche()) != '\r') {
            *stringa[i++] = inputChar;
            *stringa = realloc(*stringa, (++size) * sizeof(char));
            printf("%d\n", sizeof(*stringa) / sizeof(*stringa[0]));
        } else if (size != 1) {
            notEnter = false;
            system("CLS");
        } else {
            printf("\n");
        }
    }
    *stringa[i] = '\0';
    *iStringa = strlen(*stringa) - 1;
    reverse = realloc(reverse, (*iStringa + 1) * sizeof(char));
}

Вот результаты теста (хотела написать привет)
h8

e8

l8

l
Как я уже сказал, 8 — это число, которое он печатает каждый раз, когда предполагается расширить массив. стринга и реверс выделены в основном as
stringa = (char*) malloc(sizeof(char))

sizeof(*stringa) / sizeof(*stringa[0]) — это размер указателя или 8 в вашей системе, разделенный на размер символа, который всегда равен 1. Таким образом вы не можете определить размер выделенного блока памяти, только размер массива в область, в которой она объявлена. Если вы используете malloc/calloc/realloc, вам нужно следить за размером самостоятельно, если вам это нужно.
Retired Ninja 21.06.2023 05:54

@Stefano Carletto, "%d" - неправильный спецификатор для печати типа size_t. Используйте printf("%zu\n", sizeof(*stringa) / sizeof(*stringa[0]));. Это не решит проблему «8 - это число, которое он печатает каждый раз», но решает другие.

chux - Reinstate Monica 21.06.2023 08:09
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
66
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Кажется, вы ожидаете, что printf("%d\n", sizeof(*stringa) / sizeof(*stringa[0])); напечатает количество символов, (пере)выделенных для *stringa.

Если да, то ответ таков: ваши ожидания неверны.

Сделаем шаг назад.

Для массивов верно, что код вроде

sizeof(array) / sizeof(array[0])

даст количество элементов массива.

Например:

int array[] = {1, 10, 100, 1000};
size_t elements = sizeof(array) / sizeof(array[0]);

присвоит elements значение 4.

Но это не то, что вы делаете.

Ваш stringa не является массивом. Ваша переменная stringa имеет указатель типа на указатель на символ.

Следовательно, *stringa имеет указатель типа на char.

Так что sizeof(*stringa) это то же самое, что sizeof(char*)

stringa[0] также является указателем на char и, следовательно, *stringa[0] является char. Это означает, что sizeof(*stringa[0]) совпадает с sizeof(char).

Теперь мы можем переписать

sizeof(*stringa) / sizeof(*stringa[0])

быть

sizeof(char*) / sizeof(char)

Поскольку sizeof(char) всегда равно 1, мы можем даже записать его как просто

sizeof(char*)

Размер указателя является фиксированным числом. Он не меняется в зависимости от объема памяти, на который указывает. В большинстве 64-битных систем (если не во всех) размер указателя равен 8. Вот почему ваш оператор печати всегда показывает 8.

КСТАТИ:

*stringa[i++] не делает того, что вы ожидаете. Проверить приоритет оператора.

reverse = ... наверное должно быть *reverse = ...

ОТ:

Код начинается с size = 1. Вы не показали нам, как вы вызываете функцию, так что это может быть правильно/преднамеренно, но это кажется довольно странным. Вы действительно ожидаете, что вызывающая сторона предоставит указатель на указатель на char, который уже указывает ровно на один динамически выделенный char? Для меня это очень странный API функций.

Другие вопросы по теме