运行时检查报告的错误一般分两类,即访问错误和泄漏。
如果启用了访问检查,运行时检查会检测并报告下列类型的错误。
问题: 尝试释放尚未分配的内存。
可能的原因: 将非堆数据指针传递给了 free() 或 realloc()。
示例:
char a[4]; char *b = &a[0]; free(b); /* Bad free (baf) */
问题: 尝试释放已释放过的堆块。
可能的原因: 多次使用同一指针调用 free()。在 C++ 中,多次对同一指针使用删除操作符。
示例:
char *a = (char *)malloc(1); free(a); free(a); /* Duplicate free (duf) */
问题: 尝试释放未对齐的堆块。
可能的原因: 将未正确对齐的指针传递给了 free() 或 realloc();更改了 malloc 返回的指针。
示例:
char *ptr = (char *)malloc(4); ptr++; free(ptr); /* Misaligned free */
问题: 尝试从未正确对齐的地址中读取数据。
可能的原因: 分别从那些没有半字对齐、字对齐或双字对齐的地址中读取 2 个、4 个或 8 个字节。
示例:
char *s = “hello world”; int *i = (int *)&s[1]; int j; j = *i; /* Misaligned read (mar) */
问题: 尝试将数据写入未正确对齐的地址。
可能的原因: 将 2 个、4 个或 8 个字节分别写入没有半字对齐、字对齐或双字对齐的地址。
示例:
char *s = “hello world”; int *i = (int *)&s[1]; *i = 0; /* Misaligned write (maw) */
问题: 尝试分配超出可用物理内存的内存。
原因: 程序无法从系统获得更多的内存。查找在未检查 malloc() 的返回值是否为 NULL(一个常见编程错误)时发生的问题时会有用。
示例:
char *ptr = (char *)malloc(0x7fffffff); /* Out of Memory (oom), ptr == NULL */
问题:尝试从数组越界内存中进行读取。
可能的原因:溢出堆块边界的迷失指针。
示例:
char *cp = malloc (10); char ch = cp[10];
问题: 尝试从不存在、未分配或未映射的内存中进行读取。
可能的原因: 溢出堆块边界或访问已被释放的堆块的迷失指针。
示例:
char *cp = malloc (10); free (cp); cp[0] = 0;
问题: 尝试从未初始化的内存中进行读取。
可能的原因: 读取尚未初始化的局部数据或堆数据。
示例:
foo() { int i, j; j = i; /* Read from uninitialized memory (rui) */ }
问题:尝试写入到数组越界内存。
可能的原因:溢出堆块边界的迷失指针。
示例:
char *cp = malloc (10); cp[10] = 'a';
问题: 尝试写入到只读内存。
可能的原因: 向文本地址写入、向只读数据区 (.rodata) 写入或向已由 mmap 设置为只读的页写入。
示例:
foo() { int *foop = (int *) foo; *foop = 0; /* Write to read-only memory (wro) */ }
问题: 尝试写入到不存在、未分配或未映射的内存。
可能的原因: 溢出堆块边界或访问已被释放的堆块的迷失指针。
示例:
char *cp = malloc (10); free (cp); cp[0] = 0;
启用了泄漏检查时,运行时检查会报告下列类型的错误。
问题: 可能的内存泄漏。没有对已分配块开始处的引用,但至少有一个对块内地址的引用。
可能的原因: 指向块开始处的唯一指针增加。
示例:
char *ptr; main() { ptr = (char *)malloc(4); ptr++; /* Address in Block */ }
问题: 可能的内存泄漏。尚未释放已分配块,程序内存中不存在对块的引用,但寄存器中存在引用。
可能的原因: 如果编译器只将程序变量保留在寄存器中,而不保留在内存中,自然会出现这种错误。编译器常常会在启用了优化功能的情况下这样处理局部变量和函数参数。如果在未启用优化功能的情况下出现这种错误,则可能是真正的内存泄漏。如果指向已分配块的唯一指针在块被释放前超出作用域,便会出现这种情况。
示例:
if (i == 0) { char *ptr = (char *)malloc(4); /* ptr is going out of scope */ } /* Memory Leak or Address in Register */
问题: 尚未释放已分配块,程序中不存在对块的引用。
可能的原因: 程序未能释放不再使用的块。
示例:
char *ptr;
ptr = (char *)malloc(1); ptr = 0; /* Memory leak (mel) */