简体   繁体   English

C:为什么字符串变量接受的字符多于其大小?

[英]C: Why string variable accepts more characters than its size?

I have following code and the out put:- 我有以下代码和输出: -

#include<stdio.h>
int main()
{
char pal_tmp[4];
printf("Size of String Variable %d\n",sizeof(pal_tmp));
strcpy(pal_tmp,"123456789");
printf("Printing Extended Ascii: %s\n",pal_tmp);
printf("Size of String Variable %d\n",sizeof(pal_tmp));
}

Out put:- 输出: -

Size of String Variable 4
Printing Extended Ascii: 123456789
Size of String Variable 4

My questions is Why String variable (character array) accepts characters more than what its capacity is? 我的问题是为什么字符串变量(字符数组)接受的字符多于其容量? Should not it just print 1234 instead of 123456789 ? 它不应该只打印1234而不是123456789吗?

Am I doing something wrong? 难道我做错了什么?

Well yes. 嗯,是。 You are doing something wrong. 你做错了什么。 You're putting more characters into the string than you are supposed to. 你在字符串中添加的字符比你想要的多。 According to the C specification, that is wrong and referred to as "undefined behaviour". 根据C规范,这是错误的并且被称为“未定义的行为”。

However, that very same C specification does not require the compiler (nor runtime) to actually flag that as an error. 但是,非常相同的C规范不要求编译器(也不要求运行时)将其标记为错误。 "Undefined behaviour" means that anything could happen, including getting an error, random data corruption or the program actually working. “未定义的行为”意味着任何事情都可能发生,包括出错,随机数据损坏或程序实际工作。

In this particular case, your call to strcpy simply writes outside the reserved memory and will overwrite whatever happens to be stored after the array. 在这种特殊情况下,对strcpy只是在保留内存之外写入,并将覆盖在数组之后发生的任何事件。 There is probably nothing of importance there, which is why nothing bad seems to happen. 那里可能没什么重要的,这就是为什么似乎没有什么不好的事情发生。

As an example of what would happen if you do have something relevant after the array, let's add a variable to see what happens to it: 作为在数组之后确实存在相关内容会发生什么的示例,让我们添加一个变量来查看它发生了什么:

#include <stdio.h>

int main( void )
{
    char foo[4];
    int bar = 0;

    strcpy( foo, "a long string here" );
    printf( "%d\n", bar );

    return 0;
}

When run, I get the result 1701322855 on my machine (the results on yours will likely be different). 运行时,我在我的机器上得到结果1701322855 (你的结果可能会有所不同)。

The call to strcpy clobbered the content of the bar variable, resulting in the random output that you saw. strcpy破坏了bar变量的内容,导致您看到的随机输出。

Well yes, you are overwriting memory that doesn't belong to that buffer ( pal_tmp ). 是的,你要覆盖不属于那个缓冲区的内存( pal_tmp )。 In some cases this might work, in others you might get a segfault and your program will crash. 在某些情况下,这可能会起作用,在其他情况下,您可能会遇到段错误,程序将崩溃。 In the case you showed, it looks like you happened to not overwrite anything "useful". 在你展示的情况下,看起来你碰巧没有覆盖任何“有用”的东西。 If you tried to write more, you'll be more likely to overwrite something useful and crash the program. 如果你试图写更多,你将更有可能覆盖有用的东西并使程序崩溃。

C arrays of char don't have a predefined size, as far as the string handling functions are concerned. 就字符串处理函数而言,C数组的char没有预定义的大小。 The functions will happily write off the end of the array into other variables ( bad ), or malloc 's bookkeeping data ( worse ), or the call stack's bookkeeping data ( even worse ). 这些函数很乐意将数组的末尾写入其他变量( ),或malloc的簿记数据( 更糟糕 ),或者调用堆栈的簿记数据( 甚至更糟 )。 The C standard makes this undefined behaviour, and for good reason. C标准使得这种未定义的行为,并且有充分的理由。

If a version of a particular function accepts a size argument to limit how much data it writes, use it . 如果特定函数的某个版本接受size参数来限制它写入的数据量,请使用它 It protects you against this stuff. 它可以保护您免受这些侵害。

C does not keep track of the size of strings (or arrays, or allocated memory, etc.), so that is your job. C不跟踪字符串(或数组,或分配的内存等)的大小,这是你的工作。 If you create a string, you must be careful to always make sure it never gets longer than the amount of memory you've allocated to it. 如果你创建一个字符串,你必须小心,始终确保它永远不会超过你分配给它的内存量。

In C language Strings are defined as an array of characters or a pointer to a portion of memory containing ASCII characters. 在C语言中,字符串被定义为字符数组或指向包含ASCII字符的内存部分的指针。 A string in C is a sequence of zero or more characters followed by a NULL '\\0' character. C中的字符串是零个或多个字符的序列,后跟NULL'\\ 0'字符。 It is important to preserve the NULL terminating character as it is how C defines and manages variable length strings. 保留NULL终止字符很重要,因为它是C定义和管理可变长度字符串的方式。 All the C standard library functions require this for successful operation. 所有C标准库函数都需要此函数才能成功运行。

For complete reference refer this 有关完整参考, 请参阅此处

Function strcpy doesn't have knowledge about the length of the character array - this function is considered as unsecure. 函数strcpy不了解字符数组的长度 - 此函数被视为不安全。

You may use strncpy, where you tell the size of the buffer and if longer argument is provided, only the memory of the buffer is used and nothing else is changed. 您可以使用strncpy,在此处告知缓冲区的大小,如果提供的参数较长,则仅使用缓冲区的内存而不更改其他内容。

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

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