C安全编程教学-声明和初始化-声明具有正确存储持续期的对象(二)_c语言

注:本课程参考文献《C安全编码标准》

 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~

目录

一.初始化数组

二.不安全代码

三.解决方案

四.练习与答案

4.1初始化整型数组

4.2不安全代码示例(字符串数组)

4.3解决方案(动态分配内存)


一.初始化数组

    在本文中C语言初始化数组是指在声明数组的同时给它赋长度。

二.不安全代码

    在这个案例中,函数init_array()返回指向某个具有自动存储持续期的字符数组的指针,调用者可以访问该数组:

char *init_array(void){
    char array[10];
    /*初始化*/
    return array;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

    当函数返回的指针指向拥有自动存储期的对象时,某些编译器会发出诊断消息,本例即属此类情况。开发者应采用高警告级别的编译设置,并处理所有由诊断消息指出的问题。

三.解决方案

    在这种情况下,解决方案的确定主要依赖于程序员的意图。如果程序员的目的是修改array数组的值,并确保这一修改在init_array()函数的作用范围之外仍然有效,那么可以在init_array()函数之外的地方声明array数组,并将它作为参数传递给init_array()函数。

#include <stddef.h>
void init_array(char *array,size_t len){
    /*Initialize array*/
    return;
}
int main(void){
    char array[10];
    init_array(array,sizeof(array)/sizeof(array[0]));
    /* ... */
    return 0;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

四.练习与答案

4.1初始化整型数组

    编写一个函数init_int_array,该函数接受一个整型数组的指针和数组的长度,然后将数组初始化为0到长度减1的序列。

答案

#include <stddef.h>  
  
void init_int_array(int *array, size_t len) {  
    for (size_t i = 0; i < len; i++) {  
        array[i] = i;  
    }  
}  
  
int main(void) {  
    int array[10];  
    init_int_array(array, sizeof(array) / sizeof(array[0]));  
    // 使用array...  
    return 0;  
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

4.2不安全代码示例(字符串数组)

    下面的init_string_array函数尝试初始化一个字符串数组,但存在安全隐患。请识别问题并给出解释。

#include <string.h>  
  
char **init_string_array(void) {  
    char array[5][10];  
    // 假设有一些初始化代码  
    return array;  
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

答案

    这段代码存在安全问题,因为array是一个具有自动存储持续期的二维数组。函数返回的是指向这个自动数组的指针,当函数执行完毕后,array的生命周期结束,返回的指针指向的内存区域不再有效。

4.3解决方案(动态分配内存)

    修改init_string_array函数,使其能够安全地返回一个字符串数组的指针。

答案

#include <stdlib.h>  
#include <string.h>  
  
char **init_string_array(size_t n, size_t len) {  
    char **array = malloc(n * sizeof(char *));  
    if (array == NULL) return NULL;  
    for (size_t i = 0; i < n; i++) {  
        array[i] = malloc(len * sizeof(char));  
        if (array[i] == NULL) {  
            // 清理已分配的内存  
            for (size_t j = 0; j < i; j++) {  
                free(array[j]);  
            }  
            free(array);  
            return NULL;  
        }  
        // 初始化每个字符串  
        strcpy(array[i], "");  
    }  
    return array;  
}  
  
int main(void) {  
    char **array = init_string_array(5, 10);  
    // 使用array...  
    // 释放内存  
    for (size_t i = 0; i < 5; i++) {  
        free(array[i]);  
    }  
    free(array);  
    return 0;  
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.

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

👇个人网站👇

 安城安的云世界

 

C安全编程教学-声明和初始化-声明具有正确存储持续期的对象(二)_c语言_02