realloc 后奇怪的字符

Weird character after realloc

我正在编写一个程序,它逐个字符地接收用户输入并在最后打印出来:

#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)时,在输出时我的行末尾会附加一个未知字符:


如果我将 ptr[num_of_chars] = curr_char; 更改为 *(ptr + num_of_chars) = curr_char; 字符消失,我可以知道为什么以及如何解决它吗?提前致谢。

考虑到这个if语句

    if (res == EOF) {
        break;
    }

下面的if语句

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

没有意义。此外,您正在尝试输出由函数 scanf 编辑的整数 return 作为字符。

一般来说函数realloc可以returnNULL。在这种情况下会出现内存泄漏,因为指针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] = '[=16=]';
    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] = '[=16=]' : ( ptr[i] = '[=16=]' );

//  puts( ptr );

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

    free( ptr );

    return 0;
}