C在缓冲区中创建额外字节

C在缓冲区中创建额外字节,c,C,今天我一直在胡闹C,当我注释掉代码中的第三个缓冲区时,我不理解输出的区别: #include <unistd.h> #include <string.h> #include <stdio.h> void main() { unsigned char letters[10]; memset(letters, 0x00, 10); memset(letters, 0x41, 10); printf(letters);

今天我一直在胡闹C,当我注释掉代码中的第三个缓冲区时,我不理解输出的区别:

 #include <unistd.h>
 #include <string.h>
 #include <stdio.h>
 void main() {
     unsigned char letters[10];
    memset(letters, 0x00, 10);
    memset(letters, 0x41, 10);
    printf(letters);
    printf(" Total buffer len: %d bytes\n",strlen(letters));

     char nletters[10];
    memset(nletters, 0x00, 10);
    memset(nletters, 0x42, 10);
     printf(nletters);
    printf(" Total buffer len: %d bytes\n",strlen(nletters));

     int nums[10];
     memset(nums, 0x00, 10);
    memset(nums, 0x43, 10);
    printf(nums);
    printf(" Total buffer len: %d bytes\n",strlen(nums));   
 return 0;
}
在缓冲区保留的情况下:

AAAAAAAAAA Total buffer len: 10 bytes
BBBBBBBBBBAAAAAAAAAA Total buffer len: 20 bytes
CCCCCCCCCC��U Total buffer len: 14 bytes
我不明白的是:

  • 注释掉第三个缓冲区如何影响其他缓冲区的大小

  • 缓冲区末尾的额外字节是什么?我如何丢失/管理它们(如果我选择连接缓冲区)

  • 为什么在选择是否注释第三个缓冲区时,打印缓冲区大小和初始化大小的差异不一致

  • 缓冲区2应该是10字节,为什么是20字节?我不想要20英镑,我只想要10英镑。我不认为这是不合理的


  • C中的
    char
    字符串实际上被称为以null结尾的字节字符串。以null结尾的位很重要,所有字符串函数都希望它知道字符串何时结束

    如果您将未终止的字符串传递给字符串函数,它将超出边界,这将导致错误

    终止符等于零,可以是整数
    0
    或字符
    '\0'

    当然,这个空终止符字符需要字符串中的空格。这意味着一个10个字符的字符串必须有11个字符的空间才能容纳终止符

    简单的第一个看起来像

    char letters[11] = { 0 };  // Space for ten character plus terminator
    // The above definition also initializes all elements in the array to zero,
    // which is the terminator character
    
    memset(letters, 'A', 10);  // Set the ten first characters to the letter 'A'
    
    printf("%s", letters);  // Never print a data string directly using printf's first parameter.
    
    printf(" Total buffer len: %d bytes\n", strlen(letters));
    
    注意更改为
    printf
    。这是因为如果您从用户那里获得字符串输入,将其作为格式字符串直接传递给
    printf
    是一个非常糟糕的安全漏洞。如果字符串包含格式化代码但没有参数,则会导致未定义的行为

    还要注意,我将
    0x41
    更改为它对应的字符。幻数是一种坏习惯,它使代码更难阅读、理解和维护。

    试试以下方法:

    memset(letters, 0x00, 10);
    memset(letters, 0x41, 9);   /* <--- see the array size minus one there */
    
    memset(字母0x00,10);
    
    memset(字母0x41,9);/*您刚刚与C程序员的黑手进行了一次重大的磨合——未定义的行为。您没有使用以null结尾的字符串,因此当您将它们视为以null结尾的字符串时,会产生奇怪的效果。你的
    printf(nums)
    应该引起你的编译器的抗议——注意它;是想帮你。(如果您使用的是
    ,那么使用
    void main()
    也是错误的。有关肮脏的详细信息,请参阅。)
    memset(letters, 0x00, 10);
    memset(letters, 0x41, 9);   /* <--- see the array size minus one there */