これら 2 つのコード スニペットの違いを理解するのに苦労しています。
// 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でフリーズします-セグメンテーション違反だと思いますが、Windowsでの開発に慣れていないため、100%確信が持てません)。ポインター演算がどのように機能するかについて明らかな何かが欠けています。char* の進行に関連している可能性がありますか?
編集:問題がインデックスのオーバーフロー (つまり (i*D + j) >= 2^32) であることを確認したので、int32_t の代わりに uint64_t を使用すると問題が解決しました。私にはまだ不明なのは、上記の最初のケースが実行され、他のケースが segfault になる理由です。