Странный персонаж после реаллока - PullRequest
1 голос
/ 23 сентября 2019

Я пишу программу, которая принимает вводимые пользователем символы за символом и распечатывает их в конце:

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


#define FACTOR 2

int main(void) {

    printf("Enter line: ");
    int curr_size = 10;
    char curr_char = 0;
    char *ptr = malloc(curr_size * sizeof(char));
    int num_of_chars = 0;

    while (1) {
        int res = scanf(" %c", &curr_char);
        if (res == EOF) {
            break;
        }
        if (res != 1) {
            printf("Error: %c is not a character", res);
            break;
        }
        if (num_of_chars == curr_size) {
            curr_size = FACTOR * curr_size;
            ptr = realloc(ptr, curr_size);
        }

        ptr[num_of_chars] = curr_char;
        num_of_chars++;
    }

    printf("%s\n", ptr);
    return 0;
}

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

output image, cant display that character on paste
Если я изменю ptr[num_of_chars] = curr_char; на *(ptr + num_of_chars) = curr_char;, символ исчезнет,могу я узнать почему и как это исправить?Заранее спасибо.

1 Ответ

1 голос
/ 23 сентября 2019

Принимая во внимание это, если утверждение

    if (res == EOF) {
        break;
    }

следующее, если утверждение

    if (res != 1) {
        printf("Error: %c is not a character", res);
        break;
    }

не имеет смысла.Более того, вы пытаетесь вывести целое число, возвращаемое функцией scanf в виде символа.

Обычно функция realloc может возвращать NULL.В этой ситуации произойдет утечка памяти, поскольку предыдущее значение указателя ptr было перезаписано

ptr = realloc(ptr, curr_size);

, и этот оператор

    ptr[num_of_chars] = curr_char;

вызовет неопределенное поведение.

Также вы пытаетесь вывести массив символов в виде строки

printf("%s\n", ptr);

, но вы не добавили массив с завершающим нулевым символом.

В этом случае следует использоватьвызовите по крайней мере, как

printf("%*.*s\n", num_of_chars, num_of_chars, ptr);

или вы должны добавить символ завершающего нуля.

И вы должны освободить выделенную память.

Программа может выглядеть как

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

#define FACTOR 2

int main(void) 
{
    size_t curr_size = 10;  

    char *ptr = malloc( curr_size * sizeof( char ) );
    ptr[0] = '\0';
    char c;

    printf( "Enter line: " );

    size_t i = 0;
    for ( ; scanf( "%c", &c ) == 1 && c != '\n'; i++ )
    {
        if ( i == curr_size )
        {
            char *tmp = realloc( ptr, curr_size * FACTOR );

            if ( tmp == NULL ) break;

            curr_size *= FACTOR;
            ptr = tmp;
        }

        ptr[i] = c;
    }

//  i == curr_size ? ptr[i-1] = '\0' : ( ptr[i] = '\0' );

//  puts( ptr );

    printf( "%*.*s", ( int )i, ( int )i, ptr );

    free( ptr );

    return 0;
}
...