(C++)ポインタに関するエラー
Q&A
解決したいこと
永続配列の実装をしていたところ、ポインタに関するエラーが出ました。エラーの出所は判明したのですが、原因がわかりません。対処の仕方を教えていただけると幸いです。
発生している問題・エラー
Segmentation fault (core dumped)
該当するソースコード
#include<bits/stdc++.h>
using namespace std;
template <typename T>
struct per_array{
int depth;
struct node;
vector<node*> v;
struct node{
bool isleaf;
node* child[20] = {};
T val;
void grow(int depth){
if (depth == 0){
isleaf = 1;
return;
}
isleaf = 0;
for (int i = 0; i < 20; i++){
node* ptr = (node*)malloc(sizeof(node));
child[i] = ptr;
}
for (int i = 0; i < 20; i++){
child[i]->grow(depth - 1);
}
return;
}
node* set(int index, T a){
if (isleaf) {
val = a;
return this;
}
return child[index % 20]->set(index / 20, a);
}
T get(int index){
if (index == 0 && isleaf) {
return val;
}
return child[index % 20]->get(index / 20);
}
node* copy(node* original, int index, T a){
if (index == 0 || original->isleaf){
val = a;
isleaf = 1;
return this;
}
isleaf = 0;
for (int i = 0; i < 20; i++){
if (index % 20 == i) {
child[i] = copy(original->child[i], index / 20, a);//おそらくエラー元
}
else child[i] = original->child[i];
}
return this;
}
};
per_array(vector<T> const a){
//aで初期化
depth = 0;
int t = 1;
while (t < (int)a.size()){
t *= 20;
depth++;
}
node n;
v.emplace_back(&n);
n.grow(depth);
for (int i = 0; i < (int)a.size(); i++){
v[0]->set(i, a[i]);
}
}
void correct(int n, T m){
//最新verのm番目を破壊的に変更
(*v.rbegin())->set(n, m);
return;
}
int update(int n, T m){
//最新verのn番目を保存的に変更(返り値は永続配列中の番号)
node* ptr;
ptr = ptr->copy(*v.rbegin(), n, m);
v.emplace_back(ptr);
return (int)(v.size() - 1);
}
void correct(int index, int n, T m){
//index番目のverのn番目を破壊的に変更
v[index]->set(n, m);
return;
}
int back(int index){
//verをindexに巻き戻す
v.emplace_back(v[index]);
return (int)(v.size() - 1);
}
T at(int n, int m){
//n番目のverのm番目を返す
return v[n]->get(m);
}
};
int main(){
vector<int> a = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5};
per_array<int> pa(a);
cout << pa.depth << endl << endl;
cout << pa.at(0, 0) << endl; //3
cout << pa.at(0, 2) << endl; //4
cout << pa.at(0, 4) << endl; //5
cout << pa.at(0, 6) << endl; //2
cout << pa.at(0, 8) << endl; //3
cout << endl;
pa.update(8, 10);//エラー発生
cout << pa.at(0, 8) << endl; //3
cout << pa.at(1, 8) << endl; //10
}
自分で試したこと
コメントアウトによるエラー元の探索
vector.push_backをvector.emplace_backに変更(成果なし)
assertマクロでnullptr関連のエラーではないかの調査(おそらくnullptrが原因でない)
C++のポインタ関連の操作に慣れていないので、対処の方法があまり取れませんでした。汚いコードではありますが、見ていただけると幸いです。