最近、C++オブジェクトの作成で問題が発生しました。この問題は多少問題のようですが、
C++ strange segmentation fault by object creation
ですが、ここのコードはオープンソースプロジェクトの一部であり、簡単なエラーはないかもしれません。オブジェクト作成による別のC++の奇妙なセグメンテーションフォールト
オブジェクト作成はメソッドで呼び出され、メソッドは2つの連続ステップで呼び出されます。
クラスは次のようにstrtokenizer.hで定義されています
class strtokenizer {
protected:
vector<string> tokens;
int idx;
public:
strtokenizer(string str, string seperators = " ");
void parse(string str, string seperators);
int count_tokens();
string next_token();
void start_scan();
string token(int i);
};
をそしてstrtokenizer.cppで、それはこのようなものです:
using namespace std;
strtokenizer::strtokenizer(string str, string seperators) {
parse(str, seperators);
}
void strtokenizer::parse(string str, string seperators) {
int n = str.length();
int start, stop;
if (flag) {
printf("%d\n", n);
}
start = str.find_first_not_of(seperators);
while (start >= 0 && start < n) {
stop = str.find_first_of(seperators, start);
if (stop < 0 || stop > n) {
stop = n;
}
tokens.push_back(str.substr(start, stop - start));
start = str.find_first_not_of(seperators, stop + 1);
}
start_scan();
}
int strtokenizer::count_tokens() {
return tokens.size();
}
void strtokenizer::start_scan() {
idx = 0;
return;
}
string strtokenizer::next_token() {
if (idx >= 0 && idx < tokens.size()) {
return tokens[idx++];
} else {
return "";
}
}
string strtokenizer::token(int i) {
if (i >= 0 && i < tokens.size()) {
return tokens[i];
} else {
return "";
}
}
次のようにstrtokenizerオブジェクトを作成する方法があります:
int dataset::read_wordmap(string wordmapfile, mapword2id * pword2id) {
pword2id->clear();
FILE * fin = fopen(wordmapfile.c_str(), "r");
if (!fin) {
printf("Cannot open file %s to read!\n", wordmapfile.c_str());
return 1;
}
char buff[BUFF_SIZE_SHORT];
string line;
fgets(buff, BUFF_SIZE_SHORT - 1, fin);
int nwords = atoi(buff);
for (int i = 0; i < nwords; i++) {
fgets(buff, BUFF_SIZE_SHORT - 1, fin);
line = buff;
strtokenizer strtok(line, " \t\r\n");
if (strtok->count_tokens() != 2) {
continue;
}
pword2id->insert(pair<string, int>(strtok->token(0), atoi(strtok->token(1).c_str())));
}
fclose(fin);
return 0;
}
read_wordmap()メソッドが初めて実行されたとき(最初のread_wordmap()呼び出し)、 'strtok'オブジェクトは約87k回作成され、2回目(2回目のread_wordmap()呼び出し)にはオブジェクトは88K回以上実行することができます。しかし、それはラインで、第二のメソッド呼び出しでは約86Kの回でエラー(いつか「セグメンテーションフォールト」と時々「メモリの破損(速い)」を)上げます:
strtokenizer strtok(line, " \t\r\n");
とのコードブロックをオブジェクトの作成は以下のように改訂されますが、エラーはありません。
strtokenizer *strtok = new strtokenizer(line, " \t\r\n");
printf("line: %s", line.c_str());
if (strtok->count_tokens() != 2) {
continue;
}
pword2id->insert(pair<string, int>(strtok->token(0), atoi(strtok->token(1).c_str())));
ようこそスタックオーバーフロー!デバッガを使用してコードをステップ実行する方法を学ぶ必要があるようです。良いデバッガを使用すると、プログラムを1行ずつ実行し、どこからずれているかを確認することができます。これはプログラミングをする場合に不可欠なツールです。さらに読む:[小さなプログラムをデバッグする方法](http://ericlippert.com/2014/03/05/how-to-debug-small-programs/) –
あなたの提案をお寄せいただきありがとうございます。私はデバッガを使用する方法を知っており、エラーが発生した行も書きました。より多くのデバッグ情報を提供する必要がありますか? – YongYoung
クラッシュしたら、理想的には 'bt'(バックトレース)を行い、関連するローカル変数などの状態を調べるべきです。 –