注:本课程参考文献《C安全编码标准》
欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~
目录
一.初始化数组
二.不安全代码
三.解决方案
四.练习与答案
4.1初始化整型数组
4.2不安全代码示例(字符串数组)
4.3解决方案(动态分配内存)
一.初始化数组
在本文中C语言初始化数组是指在声明数组的同时给它赋长度。
二.不安全代码
在这个案例中,函数init_array()返回指向某个具有自动存储持续期的字符数组的指针,调用者可以访问该数组:
char *init_array(void){
char array[10];
/*初始化*/
return array;
}
当函数返回的指针指向拥有自动存储期的对象时,某些编译器会发出诊断消息,本例即属此类情况。开发者应采用高警告级别的编译设置,并处理所有由诊断消息指出的问题。
三.解决方案
在这种情况下,解决方案的确定主要依赖于程序员的意图。如果程序员的目的是修改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;
}
四.练习与答案
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;
}
4.2不安全代码示例(字符串数组)
下面的init_string_array
函数尝试初始化一个字符串数组,但存在安全隐患。请识别问题并给出解释。
#include <string.h>
char **init_string_array(void) {
char array[5][10];
// 假设有一些初始化代码
return array;
}
答案:
这段代码存在安全问题,因为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;
}
非常感谢您花时间阅读我的博客,希望这些分享能为您带来启发和帮助。期待您的反馈与交流,让我们共同成长,再次感谢!
👇个人网站👇
安城安的云世界