当以不同的方式为两个指针分配字符串时,strcpy的行为会有所不同
对不起,我可能会问一个愚蠢的问题,但我想了解以下作业有什么不同吗?strcpy在第一种情况下有效,但在第二种情况下无效当以不同的方式为两个指针分配字符串时,strcpy的行为会有所不同,c,C,对不起,我可能会问一个愚蠢的问题,但我想了解以下作业有什么不同吗?strcpy在第一种情况下有效,但在第二种情况下无效 char *str1; *str1 = "Hello"; char *str2 = "World"; strcpy(str1,str2); //Works as expected 编译器是如何理解每个赋值的?请澄清。对不起,这两个例子都是非常错误的,都会导致未定义的行为,可能会崩溃,也可能不会崩溃。让我试着解释一下原因: str1是一个悬空指针。这意味着str1指向
char *str1;
*str1 = "Hello";
char *str2 = "World";
strcpy(str1,str2); //Works as expected
编译器是如何理解每个赋值的?请澄清。对不起,这两个例子都是非常错误的,都会导致未定义的行为,可能会崩溃,也可能不会崩溃。让我试着解释一下原因:
是一个悬空指针。这意味着str1
指向内存中的某个地方,写入str1
可能会产生任意后果。例如,崩溃或重写内存中的某些数据(例如,其他局部变量、其他函数中的变量,一切皆有可能)str1
- 行
也是错误的(即使*str1=“Hello”
是一个有效的指针),因为str1
具有类型*str1
(不是char
),并且是悬挂的char*
的第一个字符。但是,您可以为它指定一个指针(str1
,键入“Hello”
),这是编译器将告诉您的类型错误char*
是一个有效的指针,但可能指向只读内存(因此崩溃)。通常,常量字符串以二进制形式存储在只读数据中,您无法对其进行写入,但这正是您在strcpy(str1,str2)中所做的代码>str2
编辑:@chqrlie在注释中要求将
\define
命名为STR1\u SIZE
而不是STR1\u LEN
。可能是为了减少混淆,因为不是“字符串”的字符长度,而是分配的缓冲区的长度/大小。此外,@chqrlie要求不要给出strncpy
函数的示例。这并不是我的选择,因为OP使用了非常危险的strcpystrcpy
,所以我选择了可以正确使用的最接近的函数。但是,是的,我应该补充一点,不建议使用strcpy
,strncpy
,以及类似的函数。对不起,这两个示例都是非常错误的,都会导致未定义的行为,可能会崩溃,也可能不会崩溃。让我试着解释一下原因:
是一个悬空指针。这意味着str1
指向内存中的某个地方,写入str1
可能会产生任意后果。例如,崩溃或重写内存中的某些数据(例如,其他局部变量、其他函数中的变量,一切皆有可能)str1
- 行
也是错误的(即使*str1=“Hello”
是一个有效的指针),因为str1
具有类型*str1
(不是char
),并且是悬挂的char*
的第一个字符。但是,您可以为它指定一个指针(str1
,键入“Hello”
),这是编译器将告诉您的类型错误char*
是一个有效的指针,但可能指向只读内存(因此崩溃)。通常,常量字符串以二进制形式存储在只读数据中,您无法对其进行写入,但这正是您在strcpy(str1,str2)中所做的代码>str2
编辑:@chqrlie在注释中要求将
\define
命名为STR1\u SIZE
而不是STR1\u LEN
。可能是为了减少混淆,因为不是“字符串”的字符长度,而是分配的缓冲区的长度/大小。此外,@chqrlie要求不要给出strncpy
函数的示例。这并不是我的选择,因为OP使用了非常危险的strcpystrcpy
,所以我选择了可以正确使用的最接近的函数。但是,是的,我可能应该补充一点,不建议使用strcpy、strncpy和类似的函数。编辑:在您编写的第一段代码中,str1=“Hello”相当于分配给str[0],这显然是错误的,因为str1未初始化,因此是无效指针。如果我们假设您的意思是str1=“Hello”
,那么您仍然是错的:
根据C规范,试图修改字符串文字会导致未定义的行为:它们可能存储在只读存储器(如.rodata)中,或者与其他字符串文字组合,因此您提供的两个代码段都会产生未定义的行为
我只能猜测,在第二个代码段中,编译器将字符串存储在某个只读存储器中,而在第一个代码段中,它没有存储字符串,因此它可以工作,但不能保证 编辑:在您编写的第一个代码段中,
*str1=“Hello”
相当于分配给str[0]
,这显然是错误的,因为str1
未初始化,因此是无效指针。如果我们假设您的意思是str1=“Hello”
,那么您仍然是错的:
根据C规范,试图修改字符串文字会导致未定义的行为:它们可能存储在只读存储器(如.rodata)中,或者与其他字符串文字组合,因此您提供的两个代码段都会产生未定义的行为
我只能猜测,在第二个代码段中,编译器将字符串存储在某个只读存储器中,而在第一个代码段中,它没有存储字符串,因此它可以工作,但不能保证 这里似乎有些混乱。两个片段都调用未定义的行为。让我解释一下原因:
char*str1代码>定义指向字符的指针,但
char *str1 = "Hello"; char *str2 = "World"; strcpy(str1,str2); //SEGMENTATION FAULT
#define STR1_LEN 128 char str1[STR1_LEN] = "Hello"; /* array with space for 128 characters */ char *str2 = "World"; strncpy(str1, str2, STR1_LEN); str1[STR1_LEN - 1] = 0; /* be sure to terminate str1 */
#define STR1_LEN 128 char *str1 = malloc(STR1_LEN); /* allocate dynamic memory for str1 */ char *str2 = "World"; /* we should check here that str1 is not NULL, which would mean 'out of memory' */ strncpy(str1, str2, STR1_LEN); str1[STR1_LEN - 1] = 0; /* be sure to terminate str1 */ free(str1); /* free the memory for str1 */ str1 = NULL;
char *str1;
char *str = "Hello";