C安全编程教学-声明和初始化-声明具有正确存储持续期的对象(三)_算法

注:本课程参考文献《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 */
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

三.优化方案

    在这个兼容的解决方案里,变量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 */
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

四.练习与答案

数组初始化

    给定一个整型数组arr,大小为5,请通过声明时直接初始化的方式为其赋值,使其元素依次为1, 2, 3, 4, 5。

int arr[5] = { /* 填空 */ };
  • 1.

答案

int arr[5] = {1, 2, 3, 4, 5};
  • 1.

数组赋值

    给定一个字符数组charArray,大小为10,请通过循环结构(如for循环)为其每个元素赋值为'a'

char charArray[10];  
for (int i = 0; i < 10; i++) {  
    /* 填空 */  
}
  • 1.
  • 2.
  • 3.
  • 4.

答案

char charArray[10];  
for (int i = 0; i < 10; i++) {  
    charArray[i] = 'a';  
}
  • 1.
  • 2.
  • 3.
  • 4.

分析代码安全性

    分析以下代码片段,判断其是否存在潜在的不安全因素,并简述原因。

void dangerous_function(char **ptr_param){  
    char local[10];  
    *ptr_param = local;  
}  
void caller(void){  
    char *ptr;  
    dangerous_function(&ptr);  
    // 使用ptr  
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

答案

    该代码存在潜在的不安全因素。原因是在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有效  
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

    这样,local数组的生命周期将贯穿整个程序运行期,ptrcaller函数作用域内始终有效。

 非常感谢您花时间阅读我的博客,希望这些分享能为您带来启发和帮助。期待您的反馈与交流,让我们共同成长,再次感谢!

👇个人网站👇

 安城安的云世界

 

C安全编程教学-声明和初始化-声明具有正确存储持续期的对象(三)_算法_02