看来当使用指向非堆内存的指针调用realloc函数时,程序就会死掉
Error(s):
Invalid memory reference (SIGSEGV)
我的str_cat
函数是否可以检测到这种情况,从而避免调用realloc
这是一个演示问题的示例程序:
//gcc 5.4.0
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int str_cat(char *dest, size_t *dest_size, char *src);
int str_cat(char *dest, size_t *dest_size, char *src) {
// if there is sufficient free space in the dest buffer, append src,
// otherwise keep doubling the allocated size of dest until it is large
// enough to append src
size_t src_len = strlen(src);
size_t dest_len = strlen(dest);
if (src_len < *dest_size - dest_len) {
memcpy(dest+dest_len, src, src_len+1);
return 0;
} else {
char *new_dest = NULL;
size_t new_size = *dest_size * 2;
while (src_len >= new_size - dest_len) {
new_size *= 2;
}
if ((new_dest = realloc(dest, new_size)) != NULL) {
dest = new_dest;
*dest_size = new_size;
memcpy(dest+dest_len, src, src_len+1);
return 0;
} else {
return -1;
}
}
}
int main(void)
{
size_t heap_buf_size=5;
char *heap_buf = malloc(heap_buf_size);
size_t stack_buf_size=5;
char stack_buf[stack_buf_size];
*heap_buf = '\0';
if (str_cat(heap_buf, &heap_buf_size, "foo")) return -1;
printf("1. heap_buf %s\n", heap_buf);
printf("1. heap_buf_size %zu\n", heap_buf_size);
if (str_cat(heap_buf, &heap_buf_size, "bar")) return -1;
printf("2. heap_buf %s\n", heap_buf);
printf("2. heap_buf_size %zu\n", heap_buf_size);
stack_buf[0] = '\0';
if (str_cat(stack_buf, &stack_buf_size, "foo")) return -1;
printf("3. stack_buf %s\n", stack_buf);
printf("3. stack_buf_size %zu\n", stack_buf_size);
/* If the line below is uncommented, the program dies
with Invalid memory reference (SIGSEGV) */
// if (str_cat(stack_buf, &stack_buf_size, "bar")) return -1;
printf("4. stack_buf %s\n", stack_buf);
printf("4. stack_buf_size %zu\n", stack_buf_size);
return 0;
}
答案 0 :(得分:4)
不,在大多数系统上以有意义的方式捕获或处理SIGSEGV是不可能的。这是因为在程序导致未映射的内存访问时,它可能已经损坏了它的堆栈或数据或代码,因此无法信任并且无法保存。如果您发现这种情况,最好立即崩溃,这样您就可以在调试器中分析转储核心。
要跟踪无效访问,valgrind是一个不错的工具,尝试valgrind ./a.out
,运行缓慢但跟踪很多事情,包括误用malloc / realloc / free。
编辑:(因为OP编辑了问题)不,除非你跟踪所有(de)分配(比如使用malloc钩子),否则无法检测指针是否是realloc / free的正确参数。