strcpy 函数无法正常工作
strcpy function not working properly
请考虑以下代码。
#include<stdio.h>
#include<string.h>
void main()
{
char a[6], b[6];
strcpy(a,"rajeev");
printf("print A:");
for(int i=0;i<strlen(a);i++)
{
printf("%c",a[i]);
}
strcpy(b,a);
printf("print B:");
for(int i=0;i<strlen(b);i++)
{
printf("%c",b[i]);
}
printf("trying to print A again");
for(int i=0;i<strlen(a);i++)
{
printf("%c",a[i]);
}
虽然 运行 这个程序在 "trying to print A again" 部分不打印任何内容,并且 strlen(a)
将为 0。这意味着源数组将为空。
你能帮我理解这背后的现象吗?
但是,将 a[6]
的声明更改为 char* a=malloc(6)
可以正常工作。
a 和 b 太小,因为 a 就在 b 之后,所以在执行 strcpy 后它的第一个字节为零。
malloc 起作用了,因为这块内存是在内存的其他地方分配的。但这只是偶然的,因为您写入的内存比分配的内存多。
对未以某种方式分配的内存的任何访问都是非法的,它是一个 UB。
您的数组不足以容纳您要存储的字符串。
C 中的字符串被定义为 空字符终止序列,这意味着正确的字符串在末尾有一个空字节。
你的数组可以容纳 6 个字节,但是你的字符串 "rajeev"
需要 7 个字节(6 个用于字母,一个用于末尾的隐式空字节。结果,你写过了数组。在数组边界外写入会调用 undefined behavior.
在动态分配内存的情况下,您再次调用了未定义的行为。在这种情况下,似乎 可以正常工作。这是未定义行为可以体现的方式之一。
要解决此问题,您的数组需要至少包含 7 个元素:
char a[7], b[7];
字符串文字 "rajeev"
的类型为 char[7]。也就是说,它具有静态存储持续时间,并存储为一个初始化为
的数组
char unnamed[] = { 'r', 'a', 'j', 'e', 'e', 'v', '[=10=]' };
因此,如果您要使用函数 strcpy
将其内容作为字符串复制,您需要在目标数组中提供足够的内存。例如
char a[7], b[7];
strcpy(a,"rajeev");
printf("print A:");
for ( size_t i = 0, n = strlen( a ); i < n; i++ )
{
printf("%c",a[i]);
}
//... and so on
考虑到函数 strlen
会计算字符数,直到遇到终止零。因此,如果字符数组不包含此字符,则函数的行为未定义。
您定义的数组 char a[6], b[6]
没有足够的 space 来容纳您要存储的字符串。
请记住,C 中的每个数组末尾都有一个空字节 [=12=]
。
您可以通过为数组提供足够的 space 来修复它:
char a[7], b[7];
请考虑以下代码。
#include<stdio.h>
#include<string.h>
void main()
{
char a[6], b[6];
strcpy(a,"rajeev");
printf("print A:");
for(int i=0;i<strlen(a);i++)
{
printf("%c",a[i]);
}
strcpy(b,a);
printf("print B:");
for(int i=0;i<strlen(b);i++)
{
printf("%c",b[i]);
}
printf("trying to print A again");
for(int i=0;i<strlen(a);i++)
{
printf("%c",a[i]);
}
虽然 运行 这个程序在 "trying to print A again" 部分不打印任何内容,并且 strlen(a)
将为 0。这意味着源数组将为空。
你能帮我理解这背后的现象吗?
但是,将 a[6]
的声明更改为 char* a=malloc(6)
可以正常工作。
a 和 b 太小,因为 a 就在 b 之后,所以在执行 strcpy 后它的第一个字节为零。
malloc 起作用了,因为这块内存是在内存的其他地方分配的。但这只是偶然的,因为您写入的内存比分配的内存多。
对未以某种方式分配的内存的任何访问都是非法的,它是一个 UB。
您的数组不足以容纳您要存储的字符串。
C 中的字符串被定义为 空字符终止序列,这意味着正确的字符串在末尾有一个空字节。
你的数组可以容纳 6 个字节,但是你的字符串 "rajeev"
需要 7 个字节(6 个用于字母,一个用于末尾的隐式空字节。结果,你写过了数组。在数组边界外写入会调用 undefined behavior.
在动态分配内存的情况下,您再次调用了未定义的行为。在这种情况下,似乎 可以正常工作。这是未定义行为可以体现的方式之一。
要解决此问题,您的数组需要至少包含 7 个元素:
char a[7], b[7];
字符串文字 "rajeev"
的类型为 char[7]。也就是说,它具有静态存储持续时间,并存储为一个初始化为
char unnamed[] = { 'r', 'a', 'j', 'e', 'e', 'v', '[=10=]' };
因此,如果您要使用函数 strcpy
将其内容作为字符串复制,您需要在目标数组中提供足够的内存。例如
char a[7], b[7];
strcpy(a,"rajeev");
printf("print A:");
for ( size_t i = 0, n = strlen( a ); i < n; i++ )
{
printf("%c",a[i]);
}
//... and so on
考虑到函数 strlen
会计算字符数,直到遇到终止零。因此,如果字符数组不包含此字符,则函数的行为未定义。
您定义的数组 char a[6], b[6]
没有足够的 space 来容纳您要存储的字符串。
请记住,C 中的每个数组末尾都有一个空字节 [=12=]
。
您可以通过为数组提供足够的 space 来修复它:
char a[7], b[7];