C语言数组溢出检测及缓冲区扩容处理技术问询
检测C语言字符串缓冲区边界失败与扩容处理
一、怎么判断写入缓冲区失败?
要逐字符往字符串里追加内容,你得盯两个关键值:缓冲区的已用字符长度(用strlen()就能拿到,因为C字符串以'\0'结尾),以及缓冲区的总分配容量——这个必须单独用变量存着,strlen()可不知道你当初malloc了多大空间。
当你要追加下一个字符时,检查:如果当前已用长度 + 1(要加的字符) + 1(结尾的'\0') > 总容量,或者更直接的判断:len + 1 >= cap(因为len是有效字符数,cap包含了'\0'的位置),这时候再硬写就会越界,也就是你说的“填充缓冲区失败”。
举个实际例子:你malloc了5字节的缓冲区(cap=5),最多能存4个有效字符加一个'\0'。当strlen(buf)等于4时,再追加任何字符都会挤掉'\0'或者直接越界,这时候就该触发扩容了。
二、扩容的具体处理步骤
既然检测到缓冲区满了,按要求扩容1个字符的步骤如下:
- 计算新容量:
new_cap = cap + 1,这样能多容纳一个有效字符(连'\0'的位置也留出来了)。 - 用
realloc()重新分配内存:把原缓冲区指针和新容量传进去,它会自动处理内存的复制(如果需要的话)。 - 检查
realloc()的返回值:如果返回NULL,说明内存分配失败——这时候原缓冲区还在,别忘了解放它,不然会内存泄漏。 - 更新缓冲区指针和容量变量:把新的指针和容量赋值回去,之后就能继续追加字符了。
三、完整可运行示例代码
#include <stdio.h> #include <stdlib.h> #include <string.h> // 逐字符追加:成功返回0,失败返回-1 int append_char(char **buf, size_t *cap, char c) { size_t len = strlen(*buf); // 检测边界:当前长度+1(要加的字符) >= 总容量(需留'\0'位置) if (len + 1 >= *cap) { size_t new_cap = *cap + 1; char *new_buf = realloc(*buf, new_cap); if (!new_buf) { // 等价于new_buf == NULL perror("realloc failed"); return -1; } *buf = new_buf; *cap = new_cap; } // 写入字符并更新终止符 (*buf)[len] = c; (*buf)[len + 1] = '\0'; return 0; } int main() { // 初始缓冲区:容量5,可存4个字符+'\0' size_t cap = 5; char *buf = malloc(cap); if (!buf) { perror("malloc failed"); return 1; } buf[0] = '\0'; // 初始化为空字符串 // 测试追加"HelloWorld" char *test_str = "HelloWorld"; for (int i = 0; test_str[i]; i++) { if (append_char(&buf, &cap, test_str[i]) != 0) { free(buf); return 1; } printf("追加'%c'后:buf=\"%s\",当前容量=%zu\n", test_str[i], buf, cap); } free(buf); return 0; }
四、几个必须注意的点
- 一定要跟踪容量:别想着靠
strlen()或者sizeof()拿容量,前者只算有效字符,后者对动态分配的指针没用,必须自己用变量存。 realloc()的错误不能忽视:如果分配失败,原内存没被释放,得手动free掉,不然会内存泄漏。- 别忘了
'\0':每次追加完字符,必须把下一个位置设为'\0',不然所有字符串函数都会读取垃圾数据。 - 初始缓冲区要初始化:刚malloc出来的内存是随机值,必须先把第一个字节设为
'\0',不然strlen()会乱读。
内容的提问来源于stack exchange,提问作者R-Rothrock
相关产品推荐
相关产品推荐

