【发布时间】:2013-08-24 09:07:21
【问题描述】:
我无法理解这两个代码 sn-ps 之间的区别是什么:
// out is of type char* of size N*D
// N, D are of type int
for (int i=0; i!=N; i++){
if (i % 1000 == 0){
std::cout << "i=" << i << std::endl;
}
for (int j=0; j!=D; j++) {
out[i*D + j] = 5;
}
}
此代码运行良好,即使对于非常大的数据集(N=100000,D=30000)也是如此。根据我对指针运算的理解,这应该给出相同的结果:
for (int i=0; i!=N; i++){
if (i % 1000 == 0){
std::cout << "i=" << i << std::endl;
}
char* out2 = &out[i*D];
for (int j=0; j!=D; j++) {
out2[j] = 5;
}
}
但是,对于一个非常大的数据集,后者不起作用(它在索引 143886 处冻结 - 我认为它存在段错误,但我不能 100% 确定,因为我不习惯在 Windows 上开发)恐怕我遗漏了一些关于指针算术如何工作的明显内容。会不会和推进char*有关?
编辑:我们现在已经确定问题是索引溢出(即 (i*D + j) >= 2^32),因此使用 uint64_t 而不是 int32_t 解决了问题.我仍然不清楚的是为什么上面的第一个案例会运行,而另一个案例会出现段错误。
【问题讨论】:
-
“不起作用”是什么意思?
-
你应该显示 out 的声明而不是评论
-
我当然希望
out数组的大小至少是D + D*N,或者你正在不属于你的内存中行走。 -
您是在 2.793GB 的字符数组上进行此计算的吗?我宁愿认为这不是最佳的。等等,这是 O(N^2) 在外循环中有一个刷新?这需要很多天才能运行
-
@soramimo:我向你保证,发布代码的唯一解释是 fast 是因为它错误。
标签: c++ pointers pointer-arithmetic