calloc为大量块

时间:2015-10-26 01:01:59

标签: c++ memory memory-management out-of-memory calloc

对于uni项目,我使用CRFSuite。 该软件在很大程度上依赖于使用calloc的动态内存分配。

当我提供更大的数据集时,程序崩溃,并且调试显示calloc无法分配足够的内存。 它返回NULLerrno设置为ENOMEM

这是失败的代码:

int crf1dc_set_num_items(crf1d_context_t* ctx, int T)
{
    const int L = ctx->num_labels;

    ctx->num_items = T;

    if (ctx->cap_items < T) {
        free(ctx->backward_edge);
        free(ctx->mexp_state);
        _aligned_free(ctx->exp_state);
        free(ctx->scale_factor);
        free(ctx->row);
        free(ctx->beta_score);
        free(ctx->alpha_score);

        // The folllowing allocation fails:

        ctx->alpha_score = (floatval_t*)calloc(T * L, sizeof(floatval_t));
        if (ctx->alpha_score == NULL) return CRFSUITEERR_OUTOFMEMORY;

        // [..snipped..]
    }

    // [..snipped..]
}

作为一个具体的例子,这对T * L = 224608388失败,即:

ctx->alpha_score = (floatval_t*)calloc(224608388, sizeof(floatval_t));
根据调试器,

sizeof(floatval_t)为8。 是的,这几乎是2 GB的内存,但是来吧...... 无论代码是编译为32位还是64位,它都会失败。 对于较少数量的块,它也会失败。

但是,如果我把它作为main中的第一件事就成功了,就像这样:

int main(int argc, char *argv[])
{
    floatval_t* foo = (floatval_t*)calloc(224608388, sizeof(floatval_t));
    if (foo != NULL)
    {
        free(foo);
    }

    // [..actual code snipped..]
}

修复此问题的最佳方法可能是重构代码,以便它不再依赖于连续内存,但我无法做到这一点。 (除了我不够聪明地理解所有细节之外,代码根本没有记录,只有隐含的变量名称,并且项目有一种奇怪的方法来实现方法...带有下划线和{{1}参数...)

那么 - 有什么方法可以摆脱这个问题吗?

我的系统是Windows 8.1 Enterprise x64机器,内存为8 GB。 我也可以尝试在不同的机器上运行它,但是如果这真的有帮助我会持怀疑态度......似乎问题出在其他地方......

我通常是C#人,而不是C / C ++专家......(我知道非常基础。)

谢谢!

0 个答案:

没有答案