合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
`C`语言中因为字符串内部没有记录长度,所以如果扩充字符串非常容易造成**缓冲区溢出(buffer overflow)**。 请看下面这张图,假设下图就是内存里面的连续空间,可以很明显的看到,此时`wolf`和`Redis`两个字符串之间只有三个空位,那么这时候如果我们要将`wolf`字符串修改为`lonelyWolf`,那么就需要`6`个空间,这时候下面这个空间是放不下的,必须要重新申请空间。但是假如说程序员忘了申请空间,或者说申请到的空间依然不够,那么就会出现后面的`Redis`字符串中的`Red`被覆盖了: ![](https://img.kancloud.cn/05/5a/055a8d24b8a1db54a08f48b10abe3051_662x139.png) 同样的,假如要缩小字符串的长度,那么也需要重新申请释放内存。否则,字符串一直占据着未使用的空间,会造成**内存泄露**。 `C`语言避免缓存区溢出和内存泄露完全依赖于人为,很难把控,但是使用`sds`就不会出现这两个问题,因为当我们操作`sds`时,其内部会自动执行**空间分配策略**,从而避免了上述两种情况的出现。 #### 空间预分配 空间预分配指的是当我们通过`api`对`sds`进行扩展空间时,假如未使用空间不够用,那么程序不仅会为`sds`分配必须要的空间,还会额外分配未使用空间,未使用空间分配大小主要有两种情况: * 假如扩大长度之后的`len`属性小于等于`1MB`(即 1024 \* 1024),那么就会同时分配和`len`属性一样大小的未使用空间(**此时`buf`数组已使用空间 = 未使用空间**)。 * 假如扩大长度之后的`len`属性大于`1MB`,那么就会分配`1MB`未使用空间大小。 执行空间预分配策略的好处是**提前分配了未使用空间备用后,就不需要每次增大字符串都需要分配空间,减少了内存重分配的次数。** #### 惰性空间释放 惰性空间释放指的是当我们需要通过`api`减小`sds`长度的时候,程序并不会立即释放未使用的空间,而只是更新`free`属性的值,这样空间就可以留给下一次使用。而为了防止出现内存溢出的情况,`sds`单独提供给了`api`让我们在有需要的时候去真正的释放内存。