边界错误是指程序读取或写入的内存超出分配的内存块的实际尺寸。边界写入错误的示例是将第11个条目写入大小为10的数组
我有一个必须在my_free()
函数实现
int main()
{
const char* string1 = "Hello, this is a string! I exist to demonstrate a common error.";
char* copy_of_string1 = (char*) my_malloc(strlen(string1));
// Whoops! Forgot to allocate space for the '\0' that ends the string.
strcpy(copy_of_string1, string1); // == boundary write error
my_free(copy_of_string1);
return 0;
}
如何捕获用户在分配的块之后直接写入一个或多个零字节的情况?
答案 0 :(得分:5)
通常的做法是分配比所需更多的内存,并在末尾放置一个标记(在过度分配的内存中)。释放时,您将检查标记是否未被覆盖。
对于我自己,我创建了malloc()
的自定义版本,它在块的开头和结尾都放置了一个标记:
+--------+
| size |
|BEEFF00D|
p-> | ... |
|DEADC0DA|
+--------+
并将返回p
而不是真正分配的块。
当我free()
块我在指针之前检查它时,值为0xBEEFF00D
,如果没有,则要释放的指针无效。然后,如果它有效,我会检查块的末尾(我已经存储了大小)并查看标记0xDEADC0DA
是否在那里,如果没有,那么边界错误。
如果一切正常,在释放(真实)块之前,我会用标记0xBEEFF00D
替换初始标记0xDEFACED
,以便捕获双free()
个错误。
我已经设置了所有内容,以便我可以添加标题并使用符号UTL_MEMCHECK
进行编译,以便每个free()
,malloc()
,calloc()
,realloc()
和strdup()
将由我的检查版本替换。当我确定一切正常时,我会在未定义UTL_MEMCHECK
的情况下重新编译。这可能对您来说太过分了,但如果您感兴趣,可以在此处找到我的代码:https://github.com/rdentato/clibutl/blob/master/src/utl.h
跳到第875行,忽略其余部分。