现在在 R-Forge 上的 v1.8.9 中修复。
- 在 中删除了意外的 50,000 列限制
fread
。感谢 mpmorley 的报告。添加了测试。
原因是我在fread.c源代码中弄错了这部分:
// *********************************************************************
// Allocate columns for known nrow
// *********************************************************************
ans=PROTECT(allocVector(VECSXP,ncol));
protecti++;
setAttrib(ans,R_NamesSymbol,names);
for (i=0; i<ncol; i++) {
thistype = TypeSxp[ type[i] ];
thiscol = PROTECT(allocVector(thistype,nrow)); // ** HERE **
protecti++;
if (type[i]==SXP_INT64)
setAttrib(thiscol, R_ClassSymbol, ScalarString(mkChar("integer64")));
SET_TRUELENGTH(thiscol, nrow);
SET_VECTOR_ELT(ans,i,thiscol);
}
根据R-exts 第 5.9.1 节,不需要循环内的 PROTECT :
在某些情况下,有必要更好地跟踪是否确实需要保护。要特别注意生成大量对象的情况。指针保护堆栈具有固定大小(默认为 10,000)并且可以变满。那么只保护视线中的所有东西并在最后取消保护数千个对象并不是一个好主意。几乎总是可以将对象分配为另一个对象的一部分(自动保护它们)或在使用后立即取消保护它们。
所以现在删除了 PROTECT,一切都很好。(似乎自从编写该文本以来,指针保护堆栈限制已减少到 50,000;Defn.h 包含#define R_PPSSIZE 50000L
。)我已经检查了 data.table C 源代码中的所有其他 PROTECT 是否有任何类似的东西,并在分配中找到并修复了一个。 c 也是(通过引用添加超过 50,000 列时),没有其他。
感谢您的报告!