我有以下代码和输出: -
#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));
}
输出: -
Size of String Variable 4
Printing Extended Ascii: 123456789
Size of String Variable 4
我的问题是为什么字符串变量(字符数组)接受的字符多于其容量?它不应该只打印1234
而不是123456789
吗?
我做错了吗?
答案 0 :(得分:8)
是的。你做错了什么。你在字符串中添加的字符比你想要的多。根据C规范,这是错误的,称为“未定义的行为”。
但是,同样的C规范不要求编译器(也不要求运行时)将其标记为错误。 “未定义的行为”意味着任何事情都可能发生,包括出错,随机数据损坏或程序实际工作。
在这种特殊情况下,您对strcpy
的调用只是写在保留的内存之外,并会覆盖在数组之后存储的任何内容。那里可能没什么重要的,这就是为什么似乎没有什么坏事发生的。
作为在数组后确实有相关内容会发生什么的示例,让我们添加一个变量来查看它发生了什么:
#include <stdio.h>
int main( void )
{
char foo[4];
int bar = 0;
strcpy( foo, "a long string here" );
printf( "%d\n", bar );
return 0;
}
运行时,我在我的机器上得到结果1701322855
(你的结果可能会有所不同)。
对strcpy
的调用破坏了bar
变量的内容,导致您看到的随机输出。
答案 1 :(得分:2)
是的,您正在覆盖不属于该缓冲区的内存(pal_tmp
)。在某些情况下,这可能会起作用,在其他情况下,您可能会遇到段错误,程序将崩溃。在你展示的情况下,看起来你碰巧没有覆盖任何“有用”的东西。如果你试图写更多,你将更有可能覆盖有用的东西并使程序崩溃。
答案 2 :(得分:1)
char
的C数组没有预定义的大小,就字符串处理函数而言。这些函数很乐意将数组的末尾写入其他变量(错误)或malloc
的簿记数据(更差)或调用堆栈的簿记数据(更糟糕)。 C标准产生了这种未定义的行为,并且有充分的理由。
如果特定函数的某个版本接受size
参数来限制它写入的数据量,使用它。它可以保护您免受这些侵害。
答案 3 :(得分:0)
C不会跟踪字符串(或数组或分配的内存等)的大小,因此这是您的工作。如果你创建一个字符串,你必须小心,始终确保它永远不会超过你分配给它的内存量。
答案 4 :(得分:0)
在C语言中,字符串被定义为字符数组或指向包含ASCII字符的内存部分的指针。 C中的字符串是零个或多个字符的序列,后跟NULL'\ 0'字符。保留NULL终止字符很重要,因为它是C定义和管理可变长度字符串的方式。所有C标准库函数都需要此函数才能成功运行。
完整参考refer this
答案 5 :(得分:0)
函数strcpy不知道字符数组的长度 - 这个函数被认为是不安全的。
您可以使用strncpy,在这里您可以告诉缓冲区的大小,如果提供的参数更长,则只使用缓冲区的内存而不会更改任何其他内容。