C 中的 Char 和 strcpy

标签 c char strcpy

我遇到了问题的一部分,其中我得到了输出,但我需要解释为什么它是真的并且有效?

char arr[4]; 
strcpy(arr,"This is a link"); 
printf("%s",arr);

当我编译并执行时,我得到以下输出。 输出:

This is a link

最佳答案

为什么它(当时)有效的简短答案是——你很幸运。超出数组末尾的写入是未定义的行为未定义的行为就是未定义,它很容易导致段错误,因为它确实产生了输出。 (尽管通常,结果是堆栈损坏)

在 C 中处理字符数组时,有责任确保分配了足够的存储空间。当您打算将数组用作字符串时,还必须为每个字符分配足够的存储空间 +1结尾处的 nul 终止 字符(这是 C 中 nul 终止 字符串的定义)。

为什么它有效?一般来说,当您请求时说 char arr[4];编译器仅保证为 arr 分配了 4 个字节。但是,根据编译器、对齐方式等,编译器实际上可能会将其用作最小分配单元的任何内容分配给 arr 。这意味着虽然您只请求了 4-bytes并且只保证有4-usable-bytes ,编译器实际上可能已经预留了 8, 16, 32, 64, or 128, etc-bytes .

或者,再说一次,你只是幸运 arr是最后一次请求的分配,并且尚未请求或写入从 byte-5 开始的内存地址。关注arr内存中。

重点是,您请求 4-bytes并且只保证有4-bytes可用的。是的,它可能适用于那个printf在代码中发生任何其他事情之前,但是您的代码完全不可靠,并且您正在玩带有堆栈损坏的俄罗斯轮盘赌(如果尚未发生)。

在 C 语言中,您有责任确保您的代码、存储和内存使用都明确定义,并且您不会陷入未定义的领域>,因为如果你这样做,所有的赌注都会被取消,并且你的代码不值得它存储的字节。

如何使代码定义良好?适当限制和验证代码中的每个必需步骤。对于您的代码片段,您可以使用 strncpy而不是strcpy然后肯定nul-terminate arr在调用printf之前,例如

char arr[4] = "";                           /* initialize all values */
strncpy(arr,"This is a link", sizeof arr);  /* limit copy to bytes available */
arr[sizeof arr - 1] = 0;                    /* affirmatively nul-terminate   */
printf ("%s\n",arr);

现在,您可以信赖 arr 的内容贯穿代码的其余部分。

关于C 中的 Char 和 strcpy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37382384/

相关文章:

c++ - 什么类型的转换适合从 unsigned char* 转换为 char*?

c - char ptr 的值在++ 递增后不会改变

c - 使用 scanf() 从键盘读取时从先前输入读取换行符

c++ - 这段代码有什么问题

c++ - Visual Studio 2013 strcpy_s 和一个字的大小

c - 查找内核数据结构的内存地址

c - 如何让 Dev-C++ 从 C 代码生成英特尔程序集?

c - strcpy 导致段错误

c - C语言中的多态性

c++ - pjsip 新调用错误...无法找到默认音频设备 (PJMEDIA_EAUD_NODEFDEV)