[英]When using a SAST tool, why do we have to use a "build wrapper" for compiled languages (e.g. C/C++)?
[英]Why and when do we have to initialize a string before using in C++?
我正在阅读一些C ++教程,发现有时会初始化字符串(“ initialized”可能不是正确的术语),有时却没有。
为什么以及何时?
我正在阅读的代码是:
char name[50];
char lastname[50];
char fullname[100];
...
cin.getline ( name, 50 );
...
cin.getline ( lastname, 50 );
fullname[0] = '\0'; // strcat searches for '\0' to cat after
strcat ( fullname, name ); // Copy name into full name
strcat ( fullname, " " ); // We want to separate the names by a space
strcat ( fullname, lastname ); // Copy lastname onto the end of fullname
请有人解释。
在C ++中,有字符数组,如char name[50]
,还有字符串类,如std::string
。
字符数组根据它们在C中的相同规则进行初始化-也就是说,如果它们是堆栈变量,则不进行初始化;如果是静态/全局变量,则在加载时将其初始化为零-但是有例外基于系统细节,因此最好是假设它们从未初始化。
字符串类(如std :: string)在对象的构造函数阶段被初始化-因此它们总是被初始化。
在您的特定代码中,您正在使用固定长度的字符数组。 它们通常以null终止,但可能并不总是-特别是cin.getline ( name, 50 );
将读取完整的50个字符,并且如果输入的字符数少于或等于49个,则该数据将以null终止,但是由于没有空间可容纳50个以上的字符,因此如果输入的字符数为50个或更多,则不会以null终止-这会对您的strcat
产生影响,因为strcat
假定数据以null结尾-您必须使用strncat
来确保代码安全。
与其他任何数据类型一样。 默认情况下,局部变量包含垃圾值。 因此,如果要读取其值,则可以对其进行初始化。 但是,如果您知道将要写入变量,则可以跳过初始化部分。
例如:
char a[20]; //local variable
包含垃圾,因此您需要在读取之前向其中写入一些有意义的数据。 但是,如果您只写它,则可以跳过初始化。
您所拥有的在堆栈上有一个分配。 编译器不保证分配的内存为空,因此您可以在其上放置垃圾,这就是为什么您需要填充0来清除垃圾的原因。
你可以做到
memset(pointer, '0', size);
例
char a[50]
memset(a, NULL, sizeof(char)*50);
当取决于您的操作时,如果您想在其中写入一些数据并进行读取,则\\ 0可能会节省您的时间,因为这是截止日期;如果您想读取所有数据,则将50字节char a [50]设置为char忽略\\ 0,因此您需要清除数据。 解决方法是清除^^内部的数据。
first_name
和last_name
不会立即初始化,因为接下来的两行会在after和full_name
到0终止符后立即对其进行初始化,因此它将表示一个空字符串,可以将其与std :: strcat连接。
char first_name[50];
char last_name[50];
// There is no need to initialize first_name and last_name,
// they will contain garbage as with any uninitialized values but they get
// overwritten here when reading from stdin anyways.
cin.getline ( first_name, 50 );
cin.getline ( last_name, 50 );
char full_name[100];
// Again full_name contains garbage, so it gets a 0 terminator here in order
// to have it represent an empty string.
full_name[0] = '\0';
// full_name had to be an empty string in order to concatenate
// onto it using strcat
strcat ( full_name, first_name );
strcat ( full_name, " " );
strcat ( full_name, last_name );
话虽这么说,这些都是C样式的字符串,您很可能更喜欢只使用std::string
。
cin.getline
不使用或检查您传入的缓冲区的原始值,因此对于该功能,无需初始化缓冲区。
相比之下, strcat
检查现有缓冲区的内容,以确定应在指定的字符串字符上附加的位置。 因此,使用strcat
,不仅必须随意初始化缓冲区,而且还必须初始化一些零字节来标记逻辑字符串末尾位置。
正如其他人所说,显示的代码非常不安全。 这是不安全的,因为(我在撰写本文时尚未对此进行评论)维护程序员可能没有意识到full_name
具有确切的缓冲区大小来容纳最大长度的名字,空格和最大大小的姓氏。 至少应该在评论中对此进行了解释。
但是比注释更好,应该使用更安全的长度检查功能。
并且除了学习之外,更好的方法是使用诸如std::string
类的字符串类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.