简体   繁体   English

创建动态字符串时的额外字节

[英]Extra byte when creating dynamic string

I have written a program to take input and dynamically allocate memory using realloc() , however there seems to be an error because if I print the final string char by char I seem to have 2 empty bytes at the end, I am sure this is going to be something silly but I have spent some time trying to discover the cause and have failed so hope to learn something here. 我已经编写了一个程序来使用realloc()进行输入并动态分配内存,但是似乎出现了错误,因为如果我按char打印最终的字符串char我似乎在末尾有2个空字节,我确定这是会变得很愚蠢,但是我花了一些时间试图找出原因,但失败了,所以希望在这里学习一些东西。

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

int main(void) {
    int count = 0;
    char *str;
    char tmp;

    str = malloc(sizeof(char));

    while (tmp != '\n') {
        tmp = getchar();

        str = realloc(str, (count + 1) * sizeof(char));

        *(str + count) = tmp;

        count += 1;

    }

    *(str + count) = '\0';

    puts(str);

    // This is just to try and see what was happening
    for (int i = 0; i <= count; i++)
        printf("str[%d] = %c\n", i, str[i]);

    free(str);
    str = NULL;

    return EXIT_SUCCESS;

}

This loop should look at least like 这个循环至少应该看起来像

for(int i = 0; i < count; i++)
                ^^^
    printf("str[%d] = %c\n", i, str[i]);

Or it would be better to write 否则写会更好

for(int i = 0; str[i]; i++)
    printf("str[%d] = %c\n", i, str[i]);

Or 要么

int i = 0;
for ( char *p = str; *p; ++p )
    printf( "str[%d] = %c\n", i++, *p );

And change these statements 并更改这些语句

while(tmp != '\n') {
tmp = getchar();

to

while ( ( tmp = getchar() ) != EOF && tmp != '\n' )

Also it would be more safe instead of this statement 也可以代替此语句更安全

str = realloc(str, (count + 0x01) * sizeof(char));

to write 来写

char *p = realloc(str, (count + 0x01) * sizeof(char));
if ( !p ) break;
else str = p;

Four things to mention here. 这里要提到四件事。

  1. while(tmp != '\\n') is reading uninitialised automatic local variable value without initialization. while(tmp != '\\n')正在读取未初始化的自动局部变量值而不进行初始化。 It invokes undefined behaviour . 它调用未定义的行为

  2. str = realloc(str, (count + 0x01) * sizeof(char)); is very bad, if realloc() fails, you'll lose the actual pointer, too. 非常糟糕,如果realloc()失败,您也会丢失实际的指针。 Always use a temporary pointer to hold the return value from realloc() and after proper error check, assign it back to the main pointer. 始终使用临时指针来保存realloc()的返回值,并在进行正确的错误检查之后,将其分配回主指针。

  3. sizeof(char) is guaranteed to be 1 . sizeof(char)保证为1 You don't need to use as a multiplier. 您无需用作乘法器。 It's redundant. 这是多余的。

  4. The for loop condition, should be i < count otherwise, you'll run into off-by-one error. for循环条件应为i < count否则,您将遇到一一错误。 C uses 0 based indexing. C使用基于0的索引。

That said, 那就是

  • You should always check for the success of the return vale of realloc() and family of functions for success before using the returned pointer. 在使用返回的指针之前,应始终检查realloc()返回值是否成功以及函数族是否成功。
  • getchar() returns an int . getchar()返回一个int You should change the type of tmp to int tmp = 0; 您应该将tmp的类型更改为int tmp = 0;

Apart from the uninitialized variable access, the two “empty characters” are: 除了未初始化的变量访问,两个“空字符”是:

  1. a newline, since you check for \\n before you read and store the next character, and 换行符,因为您在读取和存储下一个字符之前先检查\\n ,并且

  2. a character in uninitialized memory since you're incorrectly looping while i <= count and not while i < count . 未初始化内存中的字符,因为您在i <= count而不是i < count错误地循环。

Use a for (;;) (infinite loop) and check if (tmp == '\\n') { break; } 使用for (;;) (无限循环)并检查if (tmp == '\\n') { break; } if (tmp == '\\n') { break; } immediately after getchar() to avoid both the uninitialized variable access and trailing newline. if (tmp == '\\n') { break; }紧跟在getchar()以避免未初始化的变量访问和结尾的换行符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM