strcpy()函数在输出中出现意外行为[重复]

utugiqy6  于 2023-10-16  发布在  其他
关注(0)|答案(2)|浏览(97)

此问题已在此处有答案

strcpy when dest buffer is smaller than src buffer(7个回答)
22天前关闭
我正在学习用C交换数组,但后来我遇到了这些问题,我没有得到想要的输出。

**问题1:**请解释一下strcpy()是如何工作的,以及如下所示的输出的原因是什么。为什么没有复制到“x”?
**问题2:**还有一个youtube用户说我们可以通过将max length分配给每个变量的方括号内的字符数组来解决这个问题,就像这样:

char x[15] = "water";
char y[15] = "soda";
char temp[15];

这是可行的,但原因是什么呢?请解释这两个问题。

代码

#include <stdio.h>
#include <string.h>

int main()
{
    char x[] = "water";
    char y[] = "soda";
    char temp[15];

    strcpy(temp, x); 
    strcpy(x, y); 
    strcpy(y, temp);

    printf("x = %s\n", x);
    printf("y = %s", y);

    return 0;
}

输出:(VS代码和代码块都给出相同的输出)

x =
y = water
mutmk8jj

mutmk8jj1#

C库函数char *strcpy(char *dest, const char *src)src指向的字符串复制到dest
请注意,如果目标数组dest不够大,而源字符串的长度太长,则可能会导致缓冲区溢出。
这仅仅是一个例子。你可以尝试这样做:

#include <stdio.h>
#include <string.h>

int main()
{
    char x[] = "water";
    char y[] = "soda";
    char temp[15];

    strcpy(temp, x); 
    strcpy(x, y); 
    strcpy(y, temp);
    printf("location of x in RAM %p - %p\n", (void*)&x[0], (void*)&x[5]);
    printf("location of y in RAM %p - %p\n", (void*)&y[0], (void*)&y[5]);
    printf("location of temp in RAM %p - %p\n", (void*)&temp[0], (void*)&temp[15]);
    printf("x = %s\n", x);
    printf("y = %s", y);

    return 0;
}

看看变量的位置,如果你在程序中使用调试器来查看变量的地址,你会发现,当你strcpy(x,y)x结尾的'\0',被放在了应该是&y[5]的地方,但它同时是&x[0]
因此,x以'\0'开头,不会打印任何内容。
你应该确保char数组的长度足够使用strcpy函数。

c9x0cxw0

c9x0cxw02#

当你像这样声明和初始化一个C char数组时:

char x[] = "water";

编译器会帮助您解决这个问题,并确定x需要能够存储正好6个char值。额外的是空终止符。
如果您执行指定长度的工作:

char x[15] = "water";

然后你就有了一个可以存储 15char值的数组。它使用提供的字符串文字进行初始化,但其他9个可用,初始化为'\0',可以安全访问。
在您的代码中,x可以包含6个字符,但y只能包含 5,因此尝试将"water"复制到y中会导致null终止符写入越界。这就是你未定义的行为的来源。
根据程序中内存的布局,结果可能是程序表面上“工作”。
这是未定义行为最危险的结果之一,因为它隐藏了问题。
分配更多的内存是避免这个问题的一种方法,但是你也可以使用像strncpy这样的函数,它允许你指定目标缓冲区的大小来防止越界写入。如果你使用它,要小心确保你的字符串以null结尾。

相关问题