【问题标题】:Unit testing C library, memory management单元测试 C 库,内存管理
【发布时间】:2009-12-14 03:56:50
【问题描述】:

我正在开发一个相当大的 C 库,现在没有任何测试。随着 API 开始最终确定,我想开始编写单元测试。

我的几乎所有函数都作用于第一个参数(结构)。

简单的单元测试方法是让pre函数调用结构处于已知状态,调用函数,然后将pre call结构与预期结果进行比较。

现在这适用于由标量类型组成的结构,但至于分配的内存,我想知道您使用的是哪种方法。

例如,想象一个图像结构,当你这样做时:

CreateImage(&img, x, y);

您希望 img->x 是 x,img->y 是 y,img->pixels 是指向足够大的东西以容纳 x * y * sizeof(pixel) 的指针。

检查前两个是微不足道的,但是 img->pixels 呢?我不是要检查 malloc 调用是否成功,因为我可以 overload malloc,但我想知道 malloc 是否被正确调用。

在这种情况下这一点尤其重要:

CreateImage(*img, x, y)
{
    img->x = x; img->y = y;
    /* do something, dhoo, that something is broken and modify x or y */
    img->pixels = malloc(x * y * sizeof(pixel)); /* wrong allocation size */
    if(!img->pixels) error("no memory");
}

我希望我的问题很清楚。

谢谢。

【问题讨论】:

  • 你的 malloc 模拟版本应该能够告诉测试工具它被调用了什么。因此,您可以将其与应该发生的情况进行比较。

标签: c unit-testing memory-management malloc


【解决方案1】:

在您的单元测试中,让重载的 malloc 函数记录调用它的值(例如,alloc_size)。

然后只需测试所有这些是否正确:

  • alloc_size % sizeof(pixel) == 0
  • alloc_size % x == 0
  • alloc_size % y == 0
  • ((alloc_size / sizeof(pixel)) / x ) / y == 1

不要只是从您正在测试的函数中复制代码 - 即。乘法 - 因为您最终可能会复制错误。

在这种情况下,您可能会复制一个错误 - 如果没有对 xy 的边界测试,那么 malloc 调用中的乘法本身就是错误的(考虑什么会发生在具有 32 位 size_tsizeof(pixel) == 4x == 40000y == 40000 的系统上。

【讨论】:

  • 好主意,与胡安的回答在同一领域。
【解决方案2】:

您可以重载 malloc 以便对其设置一些期望值。既然您在进行调用之前就知道它需要分配多少内存,那么您就可以这样做。

SetMallocExpectation(x * y * sizeof(pixel));
CreateImage(&img, x, y);
if ( InvalidMalloc() ) {
    // The malloc call was with a different size 
}
ResetMalloc();

至于实现,我认为它看起来像这样

size_t mallocExpectations[SOME_SIZE];
int mallocCur = 0;
int mallocError = 0;
int numExpectations = 0;

void* MyMalloc(size_t size) {

    if ( size != mallocExpectations[mallocCur++] ) {
        mallocError = 1;
    }

    return (*malloc)(size);
}

void SetMallocExpectation(size_t size) {
    mallocExpectations[numExpectations++] = size;
}

int InvalidMalloc() {
    return mallocError;
}

void ResetMalloc() {
    mallocCur = 0;
    mallocError = 0;
    curExpecations = 0;
}

【讨论】:

    【解决方案3】:

    另一个想法是尝试将malloc 创建的缓冲区填充到最大大小,然后使用 Valgrind 运行您的测试套件。这应该会暴露分配问题。使用 Valgrind 运行它对其他方面也很有帮助,例如检测内存泄漏。

    【讨论】:

      猜你喜欢
      • 2011-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-14
      • 1970-01-01
      • 2014-04-09
      • 1970-01-01
      • 2012-12-23
      相关资源
      最近更新 更多