动态的缓存区

1
2
3
4
5
6
7
8
int main() { 
struct strbuf sb;
strbuf_init(&sb, 10);
strbuf_attach(&sb, "xiyou", 5, 10);
assert(strcmp(sb.buf, "xiyou") == 0);
strbuf_addstr(&sb, "linux");
assert(strcmp(sb.buf, "xiyoulinux") == 0);
strbuf_release(&sb);}

要想实现这个缓存区需要进行四个步骤依次处理

  • strbuf_init 的作用是开辟一个新的内存空间
  • strbuf_attach 将首次的字符串,放进新的缓冲区中
  • strbuf_addstr 继续追加新的字符串
  • strbuf_free 对其进行释放,释放整个内容空间
1
2
3
4
5
struct strbuf {  
int len;
int aclloc;
char *buf;
}sb;

定义一个结构体

int len 当前缓存区的(字符串长度)
int aclloc 当前缓存区的 (字符串容量) // 主要用于开辟一个内容空间
char * buf 构建一个字符型的指针

初始化 strbuf

1
2
3
4
5
6
7
8
9
10
void strbuf_init(struct strbuf *sb, int alloc) {  
sb->buf = (char *)malloc(alloc);
if (!sb->buf) {
fprintf(stderr, "Memory allocation failed\n");
exit(1);
}
sb->buf[0] = '\0'; // 初始化为空字符串
sb->len = 0;
sb->alloc = alloc;
}

首先对传入的参数进行分析,结构体进行储存
len 表示一个当前字符串需要的长度
aclloc 表示当前的内存中可用的长度

  1. 分配传入内容的大小
    sb -> buf = (char *)maclloc(alloc)
  2. 判断是否正确的分配内容,如果没有成功打印进行一个提升
    1
    2
    3
    4
    if (!sb->buf) {  
    fprintf(stderr, "Memory allocation failed\n");
    exit(1);
    }
1
2
3
4
5
6
3. 对len , aclloc 进行一个初始化
```c
sb->buf[0] = '\0'; // 初始化为空字符串
sb->len = 0;
sb->alloc = alloc; // 赋予当前可以容纳的字符串容量值
}

附加字符串进入*strbuf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void strbuf_attach(struct strbuf *sb, const char *str, int len, int alloc) {  
// 确保 alloc 足够大
if (alloc < len + 1) {
alloc = len + 1;
}

// 释放旧缓冲区
free(sb->buf);

// 分配新内存
sb->buf = (char *)malloc(alloc);
if (!sb->buf) {
fprintf(stderr, "Memory allocation failed\n");
exit(1);
}

// 复制字符串
memcpy(sb->buf, str, len);
sb->buf[len] = '\0'; // 确保以 '\0' 结尾
sb->len = len;
sb->alloc = alloc;
}
  1. 确保当前的缓冲区特别大, 如果当前的字符串容量小于新加入的字符串长度,至少保证当前容量大于(len +1)
    1
    2
    3
    	if (alloc < len + 1) {  
    alloc = len + 1;
    }
1
2
3
4
5
6
7
8
9

2. 释放旧的缓冲区
3. 分配新的内容空间
```c
sb->buf = (char *)malloc(alloc);
if (!sb->buf) {
fprintf(stderr, "Memory allocation failed\n");
exit(1);
}
  1. 复制字符串进入结构体当中
    1
    memcpy(sb->buf, str, len);
1
2
3
4
5
5. 处理尾任务,将数据处理完整
```c
sb->buf[len] = '\0'; // 确保以 '\0' 结尾
sb->len = len;
sb->alloc = alloc;

追加字符串到 strbuf

  1. 计算新的字符串长度
    1
    2
    int str_len = strlen(str);
    int new_len = sb ->len + str_len;
1
2
3
4
5
6
7
8
9
2. 检查是否需要扩容
```c
if (new_len + 1 > sb->alloc) { // +1 留出 '\0' 空间
int new_alloc = sb->alloc * 2;
if (new_alloc < new_len + 1) {
new_alloc = new_len + 1; // 至少满足新长度
}
char *new_buf = (char *)realloc(sb->buf, new_alloc); // 调整缓冲区的大小

  1. 检查是否正确正确开通
1
2
3
4
5
6
7
    if (!new_buf) {  
fprintf(stderr, "Memory reallocation failed\n");
exit(1);
}
sb->buf = new_buf;
sb->alloc = new_alloc;
}
  1. 追加字符串,继续指向新的地址
    1
    2
    3
    memcpy(sb->buf + sb->len, str, str_len);  
    sb->len = new_len;
    sb->buf[sb->len] = '\0'; // 确保以 '\0' 结尾
1
2
3
4
5
6
7
​```c
void strbuf_release(struct strbuf *sb) {
free(sb->buf);
sb->buf = NULL;
sb->alloc = 0;
sb->len = 0;
}

释放buf创建的的内容空间
释放指针 sb ->buf = NULL
alloc 和 len