C динамическое выделение памяти

Я изучаю C, но я все еще нуб. Я пишу программу в качестве упражнения по динамическому распределению памяти, которая берет от пользователя текст неизвестной длины и возвращает этот текст без пробелов, табуляции, специальных символов или цифр. Программа, кажется, работает нормально, за исключением того, что часть текста кажется измененной на неизвестные символы по неизвестным причинам. Вот код:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char *pstring;
    pstring = (char *)malloc( sizeof(char));

    char c = '$';

    int i = 0;
    while(c != '\n')
    {
        c = getchar();
        if(isalpha(c))
        {
            pstring[i] = c;
            realloc(pstring, (i+2)*sizeof(char));
            i++;
        }
    }

    int j;
    for(j = 0; j < i; j++)
    {
        printf("%c", pstring[j]);
    }

    return 0;
}

Работает нормально: введите здесь описание изображения

Проблема в следующем: введите здесь описание изображения


person Nora Amer    schedule 11.09.2015    source источник
comment
Обязательное предупреждение: приводить результат malloc?.   -  person Paul R    schedule 11.09.2015
comment
Обязательно: sizeof(char) равен 1 или вы не используете C.   -  person mlp    schedule 11.09.2015


Ответы (2)


Функция realloc может расширить существующую память, но она также может (и, вероятно, в большинстве случаев так и происходит) выделить полностью новую память. Он возвращает перераспределенную память, и вы не используете возвращенный указатель.

Кроме того, если realloc завершится ошибкой, будет возвращено NULL, поэтому не назначайте возвращенный указатель переменной, которую вы используете в вызове realloc, иначе вы потеряете исходный указатель. Используйте временную переменную и проверьте наличие NULL, а затем переназначьте фактическую переменную указателя.

Кстати говоря, sizeof(char) всегда указывается как 1.


Напоследок слово предупреждения. То, как вы обрабатываете «строку» прямо сейчас, отлично работает (после устранения проблемы, которая у вас есть сейчас или конечно), но если вы хотите обрабатывать данные как «правильную» строку C, вам нужно выделить один дополнительный символ, потому что C строки заканчиваются нулевым символом '\0' (не путать с нулевым указателем NULL).

Если в вашей строке нет этого признака конца, использование любой стандартной строковой функции приведет к неопределенному поведению, поскольку оно, скорее всего, выйдет за пределы выделенной памяти.

person Some programmer dude    schedule 11.09.2015

Как сказал Иоахим Пилеборг, realloc может переместить блок памяти в новое место, и мы должны изменить указатель на это новое место.

Вот полезная ссылка о функции realloc Теперь мой рабочий код

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char *pstring, *ptemp;
    pstring = (char *)malloc( sizeof(char));

    char c = '$';

    int i = 0;
    while(c != '\n')
    {
        c = getchar();
        if(isalpha(c))
        {
            pstring[i] = c;
            ptemp = realloc(pstring, (i+2)*sizeof(char));
            if(ptemp != NULL)
            {
                pstring = ptemp;
                i++;
            }
        }
    }

    int j;
    for(j = 0; j < i; j++)
    {
        printf("%c", pstring[j]);
    }

    return 0;
}
person Nora Amer    schedule 12.09.2015