首页 > 试题广场 >

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

[问答题]
分析下面代码可能会有什么风险?
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)
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是保留字,而不是关键字,理论上可以作变量名或数组名,且能编译通过,但一个好的编程习惯是不建议这样做的
(2)“01234567891”是“const char *”类型,不可赋值给“char *”类型,故应改为const char * str = "01234567891"
(3)"01234567891"大小为12个字节(加上结束符),但string数组只有10个字节空间,在调用strcpy函数时发生越界,有安全隐患
发表于 2020-10-23 22:31:48 回复(2)

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

  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++ STL中的一个类名,定义在<string>中,由于string不是关键字或保留字,所以可以将其用作变量名、函数名等标识符,不过这样做会导致无法使用标准库中的string类,并且容易引起混淆,一个好的编程习惯是不建议这样做的
  2. 在 C++11 及更高版本中,不允许直接将字符串字面量转换为char *类型。在 C++11 之前,字符串字面量可以隐式地转换为char *,但这种转换存在一些潜在的问题,比如可能导致内存管理问题和安全漏洞。为了解决这些问题,C++11 引入了更严格的类型安全规则,禁止了这种隐式转换。可以通过const char* str1="012345678901";或者std::string str1=”01234567890“;两种方式接受字符串面量;
  3. 缓冲区溢出。string字符数组声明为10个字符空间的数组,但str1字符串长度为11,通过strcpy函数进行复制会发生缓冲区溢出的风险: 
    • 缓冲区溢出可能会破坏相邻的内存区域,导致数据损坏。如果其他重要的数据结构或变量被覆盖,可能会导致程序出现错误的行为;
    • 导致程序崩溃;
    • 引发安全漏洞,攻击者可以利用缓冲区溢出漏洞来执行恶意代码。
 
发表于 2024-10-20 23:34:26 回复(0)
1.数组越界
发表于 2024-09-15 14:16:18 回复(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)