首页 > 试题广场 >

分析下面代码有什么问题?

[问答题]
分析下面代码可能会有什么风险?
void test1() 
{ 
    char string[10]; 
    char* str1 = "01234567891"; 
    strcpy( string, str1 ); 
} 
字符串str1需要11个字节才能存放下(包括末尾的’\0’),而string只有10个字节的空间,strcpy会导致数组越界;  
编辑于 2021-03-15 18:59:31 回复(14)
首先,在c语言中,string可以用作变量名,
但是在c++中,这样使用string是错误的,c++保留了string作保留字;
其次,编译器会自动将数组名作为指向数组首地址的指针处理;保证char *strcpy(char* dest, const char *src);符合原型声明规定;即函数内元素必须是指针;【strcpy()在头文件#include<string.h>内包含】;
str1是指向字符的指针/字符数组,使用字符串:“0123456789”对其进行赋值占用11字节的空间【包括字符串结束标志符:\0】;
声明数组string[]的时候,给了10 个字节的内存空间,进行拷贝实现的时候,会出现数组越界;


发表于 2018-04-17 17:22:59 回复(0)
(1)严格区分的话,string是保留字,而不是关键字,理论上可以作变量名或数组名,且能编译通过,但一个好的编程习惯是不建议这样做的
(2)“01234567891”是“const char *”类型,不可赋值给“char *”类型,故应改为const char * str = "01234567891"
(3)"01234567891"大小为12个字节(加上结束符),但string数组只有10个字节空间,在调用strcpy函数时发生越界,有安全隐患
发表于 2020-10-23 22:31:48 回复(1)
strcpy(s1,s2);strcpy函数的意思是:把字符串s2中的内容copy到s1中,连字符串结束标志也一起copy. 这样s1在内存中的存放为:ch\0;故所需的空间是11个字节,而规定的字符数组string是10个字节,虽然编程时没有报错,但还是存在数组越界情况
发表于 2017-06-21 19:16:13 回复(0)
strcpy(s1,s2);strcpy函数的意思是:把字符串s2中的内容copy到s1中,连字符串结束标志也一起copy.
这样s1在内存中的存放为:ch\0;故所需的空间是11个字节,而规定的字符数组string是10个字节,虽然编程时没有报错,但还是存在数组越界情况
发表于 2017-02-27 16:56:24 回复(0)
char*前边还需要加const才可以
发表于 2019-10-08 19:33:04 回复(0)
1.string是C++中的一个类名,不可以作为变量名 2.strcpy函数的实现是以'\0'判定拷贝结束的,并且会给目标字符串结尾加一个'\0',所以会向目标字符数组拷贝11个元素,问题就在于如果第十个元素后的内存没被分配,那么这个目标字符数组中存的字符串是可以被打出来了,如若不然,第11个元素的内存空间很容易被改写,导致字符串打印出错~
发表于 2019-06-15 20:16:00 回复(0)
string[10]只有11个char类型的内存空间。
str1字符串有12个字符,所以强行将str1的内容拷贝到string的数组内,导致数组越界,造成严重的后果。
发表于 2021-08-16 21:25:23 回复(0)
这个题实际上考察是是strcpy的实现
strcpy函数存在的三个问题:(1)无结束符(2)内存不足(3)内存重叠
char* strcpy(char* dst,const char* src){
    assert(dst!=NULL&&src!=NULL);
    char *ret=dst;//ret是还回值
    while((*dst++=*src++)!='\0');//注意不管是*p++还是*(p++)都是先取地址然后在取出实际的值
    //循环判断条件是以结束符\0,所以src一定不能不带结束符
    return ret;
}


编辑于 2020-04-13 15:12:03 回复(0)
string1里面包含10个字符,再加结束符总共十一个。而string只有10个空间,然而在调用strcpy函数时,string字符串会强行扩充原来字符串最后一个字符地址之后的一个字符空间,导致第十一个字符会覆盖后面未知空间里的数据。有隐患,但是运行结果一般是没问题,这是strcpy一直存在的问题。
编辑于 2019-03-06 21:04:55 回复(0)
越界,结果未知
发表于 2018-11-24 19:41:34 回复(0)
复制的时候,会把字符串最后的'\0'一起复制,所以会数组越界。这是非常危险的!一旦出错,调试很困难!
发表于 2017-08-18 16:52:49 回复(0)
代码本身没有错误,如果将str1拷贝到string中,string的长度会增加,并且也可以正确的输出string。
(c、java代码都测试过,没有问题)
但是存在潜在的危险,string定义的长度是10,而拷入str1之后string的长度增为11,也就是说,在内存中,如果紧接string之后有内容,将被覆盖,这样会导致string之后的内存存取错误。
发表于 2016-03-01 10:47:59 回复(13)

①在C++不允许const char*的值对char*类型实体化;但在c中是允许这样的初始化方式。
②C++不允许将变量名声明为string,string是c++的类类型关键字;c中可以,c没有字符串,只有字符数组。
③代码中的str是11位数字“01234567891”,如果要算上‘\0\',应该是要12字节的字符数组才能准确无误存储;string这个字符数组只有10字节,导致strcpy后的string内容是0123456789...。注意...,因为在str1中到达字符9后的下一个字符不是’\0‘,它仍会继续拷贝,直到’\0',而string你只分配了10个字节栈内存给它,它就只能查看这10个字节内容,这种行为是未定义的,回导致string的周围的内存内容被破坏。
④string应当分配12个字节,因为11个字节中,你没有存取到str1中的'\0',其内容是"01234567891..."而不是"01234567891",导致后续如果使用strlen会发生错误,因为strlen的机制是达到'\0'停止

个人理解,欢迎大佬指证

发表于 2020-07-16 15:17:17 回复(6)
知识点:
  • 允许用字符串字面值对字符数组初始化,\0也会拷贝进去。
  • 编译器会自动把数组名字替换为指向数组首元素的指针。
  • strcpy为c风格字符串的函数,定义在头文件cstring中,strcpy(p1,p2)将p2拷贝给p1,返回p1。

存在问题:
  • string不能用作变量名,string是c++中的标准库类型。
  • str1是一个指向字符的指针/字符数组,字符串字面值"0123456789"的长度为11,strcpy函数将str1拷贝给string,但string大小为10,str大小为11,导致数组越界。
发表于 2017-05-02 10:08:04 回复(3)

这段代码可能会存在以下风险:

  1. 缓冲区溢出:变量string是一个长度为 10 的字符数组,而str1是一个长度为 12 的字符串(包括终止符'\0')。当使用strcpy函数将str1复制到string中时,会导致缓冲区溢出,超出string数组的边界。这可能会覆盖相邻内存区域的内容,导致未定义的行为,缓存区溢出攻击可以看这里:https://csguide.cn/cpp/memory/memory_errors.html

  2. 字符串截断:由于string数组长度较小,无法容纳str1的完整内容,strcpy函数会将部分内容复制到string中,但不会自动截断。这可能导致string不是以终止符 '\0' 结束,进而引发字符串操作相关的问题。

可以采取以下措施:

  1. 确保目标缓冲区足够大,可以容纳要复制的字符串及其终止符。在本例中,将string数组的大小增加到至少 12。

  2. 使用更安全的字符串复制函数,如strncpy,它允许指定要复制的最大字符数,避免缓冲区溢出。确保在复制后手动添加终止符 '\0'。


发表于 2023-05-22 13:35:08 回复(0)
1.string在c++中为关键字 不能用于声明变量
2.报错const char* 类型的值不能用于初始化char* 类型的实体 
解决办法:强转为char* 类型  
void test()
{
    char * str=(char* )"111111";
}
3.越界
发表于 2022-10-12 12:33:41 回复(0)
越界
发表于 2022-06-17 11:19:46 回复(0)
  1. 字符串str1需要12个字节才能存放下(包括末尾的’\0’),而string只有10个字节的空间,strcpy会导致数组越界;
  2. string作为变量名不合适。可能造成潜在的命名冲突
发表于 2022-04-20 08:16:43 回复(0)
数组越界,还有一个'\0',数组大小应该是11
发表于 2022-01-05 10:56:06 回复(0)