-3

次のコードは、セグメンテーション違反を示しています。私が把握しているすべての間違いは、printf() ステートメントを含む行にありますが、その理由と修正方法がわかりません。

#include<iostream>
#include<stdio.h>
#include<string>
#include<readline/history.h>
#include<readline/readline.h>

using namespace std;
int main()
{
    using_history();
    string command("history");
    add_history(command.c_str());
if (command == "history")
{
    cout<< "hello\n";
    for(int i = 0 ; i < history_length ; i++)
    {
        cout<<"in there\n";
        HIST_ENTRY *entry = history_get(i);
        cout<<"till here\n";
        printf("%5d %s", i , entry->line);
    }
}
return 0;
}
4

2 に答える 2

2

ドキュメントから:_readline

機能: から始まるHIST_ENTRY * history_get (int offset)
位置 の履歴エントリを返します (セクション 2.4 履歴変数を参照してください)。そこにエントリがない場合、または履歴の長さよりも大きい場合は、NULL ポインタを返します。offsethistory_baseoffset

コードは無視しhistory_base、0 からオフセットします。

その結果、history_get成功できず、コードがチェックしない NULL ポインターを返しています。このポインターを逆参照しようとすると、セグメンテーション違反が発生します。

このループを次のように記述します。

for (int i = 0; i < history_length; i++) {
    HIST_ENTRY* entry = history_get(history_base + i);
    if (entry)
       printf("%5d %s", i, entry->line);
    else
       printf("%5d ERROR!", i);
}

history_base呼び出しにオフセットを追加し、history_getエラー チェックを追加したことに注目してください。

使用する関数のドキュメントを読み、エラー チェックを実行し、デバッガーを使用することは、プログラミングの重要な才能です。

于 2012-11-03T19:20:42.017 に答える
0

へのオフセット パラメータはhistory_get(offset);から始まりhistory_baseます。また、history_lengthは履歴内のエントリの総数であるためhistory_base、ループ条件に を追加する必要があります。

つまり、ループを次のように書き直す必要があります。

for(int i = history_base ; i < history_base + history_length ; i++)

{
    ...
}
于 2012-11-03T19:09:50.930 に答える