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

时间:2013-05-23 05:50:56

标签: c string

我有以下代码和输出: -

#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吗?

我做错了吗?

6 个答案:

答案 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,在这里您可以告诉缓冲区的大小,如果提供的参数更长,则只使用缓冲区的内存而不会更改任何其他内容。