You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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个字符的步骤如下:

  1. 计算新容量:new_cap = cap + 1,这样能多容纳一个有效字符(连'\0'的位置也留出来了)。
  2. 用realloc()重新分配内存:把原缓冲区指针和新容量传进去,它会自动处理内存的复制(如果需要的话)。
  3. 检查realloc()的返回值:如果返回NULL,说明内存分配失败——这时候原缓冲区还在,别忘了解放它,不然会内存泄漏。
  4. 更新缓冲区指针和容量变量:把新的指针和容量赋值回去,之后就能继续追加字符了。

三、完整可运行示例代码

#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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 15:20:32