技术c技术分享动态的缓存区
Firm1 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 表示当前的内存中可用的长度
- 分配传入内容的大小
sb -> buf = (char *)maclloc(alloc)
- 判断是否正确的分配内容,如果没有成功打印进行一个提升
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) { 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'; sb->len = len; sb->alloc = alloc; }
|
- 确保当前的缓冲区特别大, 如果当前的字符串容量小于新加入的字符串长度,至少保证当前容量大于(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
| 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 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 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 2 3
| memcpy(sb->buf + sb->len, str, str_len); sb->len = new_len; sb->buf[sb->len] = '\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