我无法理解这两个代码片段之间的区别是什么:
// 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 解决了问题。我仍然不清楚的是为什么上面的第一个案例会运行,而另一个是段错误。