1. ホーム
  2. c++

[解決済み] 以下のコードでバスエラーが発生します。

2022-02-02 22:16:56

質問

私のコードでバスエラーが発生します。このコードでは、数字を単語に変換しようとしていますが、私のロジックに欠陥があることは分かっています。しかし、その前に、このコードをg++でコンパイルして実行したところ Mac , このコードをそのまま実行させようとすると、バスエラーが発生するんです。何か手助けがあれば、よろしくお願いします。

このコードを実行すると、次のような出力が得られます。どこでエラーが発生したかを追跡するためのデバッグメッセージもあります。

    数字を入力:1234
    メイン1:数字は:234
    Function1: 数値は234
    2
    二百
    34Function2: 数値は34
    関数3:数値は34
    バスエラーです。10


#include <iostream>
#include <string>

using namespace std;
char *convert_number(int);

char *tens[] = {"", "ten", "twenty", "thirty", "forty",
                "fifty", "sixty", "seventy", "eighty", "ninety"};

char *words[] = {"zero", "one", "two", "three", "four",
                 "five", "six", "seven", "eight", "nine",
                 "ten", "eleven", "twelve", "thirteen", "fourteen",
                 "fifteen", "sixteen", "seventeen", "eighteen", "ninteen"};

char *place[] = {"", "hundred", "thouands", "million", "billion", "trillion"};


int main(int argc, char **argv)
{
    int number, conv_num, places;
    places = 1;
    char *string = new char[1000];
    char *temp_string = new char[100];
    cout << "Enter a number:";
    cin >> number;
    string = " ";
    if (number >= 1000)
    {
        while(number >= 1)
        {
            conv_num = number % 1000;
            cout << "main 1:numbers are:" << conv_num << endl;
            temp_string = convert_number(conv_num);
            string =strcat(string, temp_string);
            string =strcat(string, " ");
            number = 0; // (number-conv_num)/1000;
            cout << "main 2:numbers are:" << endl;
            //cout << conv_num << ":" << number << endl;
        }
    }
    else
    {
        string = convert_number(number);
        string = strcat(string, " ");
    }
    cout<<"Main: The word is :"<<string<<endl;
}

char *convert_number(int number)
{
    int divisor;
    char *word;
    word = new char[100];
    divisor = 10;
    cout << "Function1: Number is " << number << endl;

    if (number >= 100)
    {
        word = strcat(word, words[number/100]);
        cout << word << endl;
        word = strcat(word, " hundred ");
        cout << word << endl;
        number = number%100;
        cout << number;
    }
    cout << "Function2: Number is " << number << endl;

    if (number >= 20)
    {
        word = strcat(word, tens[number/10]);
        word = strcat(word, " ");
        if (number%divisor >= 1)
        {
            word=strcat(word, words[number%divisor]);
            word =strcat(word, " ");
        }
    }
    cout << "Function3: Number is " << number << endl;

    if (number < 20)
    {
        word = strcat(word, words[number]);
        word = strcat(word, " ");
    }
    cout << "Returning word:" << word;
    return word;
}

解決方法は?

バスエラーが発生するのは、書き込み不可能な領域(すなわち、文字定数やその末尾)に書き込みを行おうとしているからです。

// Good: allocate 100 bytes to string 
char *string = new char[100];

// Bad! Compiler warns you that assigning character const to char* is wrong.
// It does not tell you that you've just leaked the 100 bytes that you allocated
/// before, but that's also true.
string=" ";

// ... some more code, and then
string = strcat(string,temp_string); // <<== HERE is the problem!

の呼び出しは strcat の終端ゼロに書き込もうとします。 string という文字列定数の終端を越えて書き込みを続けます。これは未定義の動作なので、プログラムがクラッシュしてしまいます。

この問題を解決するには " "string に代入するのではなく string のポインタを使用します。