注:本课程参考文献《C安全编码标准》
欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~
目录
一.前言
C语言中的数组赋值可以通过在声明时直接初始化,或者在声明后通过循环或逐个元素赋值的方式完成。初始化赋值时,可以在声明数组的同时用大括号{}
包含一系列值来为数组元素赋值。对于已经声明的数组,可以使用循环结构(如for
循环)或指定下标的方式为数组的每个元素逐个赋值。
二.不安全代码
用另一种方式来说,这段代码示例展示了函数squirrel_away()
的行为,它把一个指向局部变量local
的指针存储到了由函数参数ptr_param
所指示的内存位置。然而,当squirrel_away()
函数执行完毕后,ptr_param
所指向的那个变量local
的生命周期已经结束,这意味着ptr_param
指向了一个已经不再有效的内存区域。
void squirrel_away(char **ptr_param){
char local[10];
/* Initialize array */
*ptr_param = local;
}
void rodent(void){
char *ptr;
squirrel_away(&ptr);
/* ptr is live but invalid here */
}
三.优化方案
在这个兼容的解决方案里,变量local
具有静态存储持续时间,所以,ptr
可以在rodent()
函数中被用来引用local
数组。
char local[10];
void squirrel_away(char **ptr_param){
/* Initialize array */
*ptr_param = local;
}
void rodent(void){
char *ptr;
squirrel_away(&ptr);
/* ptr is valid in this scope */
}
四.练习与答案
数组初始化
给定一个整型数组arr
,大小为5,请通过声明时直接初始化的方式为其赋值,使其元素依次为1, 2, 3, 4, 5。
int arr[5] = { /* 填空 */ };
答案
int arr[5] = {1, 2, 3, 4, 5};
数组赋值
给定一个字符数组charArray
,大小为10,请通过循环结构(如for循环)为其每个元素赋值为'a'
。
char charArray[10];
for (int i = 0; i < 10; i++) {
/* 填空 */
}
答案
char charArray[10];
for (int i = 0; i < 10; i++) {
charArray[i] = 'a';
}
分析代码安全性
分析以下代码片段,判断其是否存在潜在的不安全因素,并简述原因。
void dangerous_function(char **ptr_param){
char local[10];
*ptr_param = local;
}
void caller(void){
char *ptr;
dangerous_function(&ptr);
// 使用ptr
}
答案
该代码存在潜在的不安全因素。原因是在dangerous_function
函数中,局部变量local
的地址被赋给了ptr_param
指向的指针。由于local
是一个局部变量,当dangerous_function
函数执行完毕后,local
的生命周期结束,ptr
将指向一个已经不再有效的内存区域。
代码优化
针对练习3中的不安全代码,请提供一个优化方案,确保caller
函数中的ptr
指针在函数作用域内始终有效。
答案
可以通过将local
数组定义为静态存储类型来优化代码,如下:
static char local[10];
void safe_function(char **ptr_param){
*ptr_param = local;
}
void caller(void){
char *ptr;
safe_function(&ptr);
// 此时ptr有效
}
这样,local
数组的生命周期将贯穿整个程序运行期,ptr
在caller
函数作用域内始终有效。
非常感谢您花时间阅读我的博客,希望这些分享能为您带来启发和帮助。期待您的反馈与交流,让我们共同成长,再次感谢!
👇热门内容👇
Orbslam3&Vinsfusion_安城安的博客-CSDN博客
👇个人网站👇