对于uni项目,我使用CRFSuite。
该软件在很大程度上依赖于使用calloc
的动态内存分配。
当我提供更大的数据集时,程序崩溃,并且调试显示calloc无法分配足够的内存。
它返回NULL
,errno
设置为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 ++专家......(我知道非常基础。)
谢谢!