I am getting a bus error in the following code

Dangerous Scholar picture Dangerous Scholar · May 24, 2012 · Viewed 16.9k times · Source

I am getting bus error in my code. With this code I am trying to convert numbers to words, but I know that there is a flaw in my logic. But before that, when I compile and run this code using g++ on Mac, I am trying to make this code run as it is and I am getting a bus error. Any help would be appreciated.

When I run the code I get following output. I have debug messages to trace where the error occurs.

    Enter a number:1234
    main 1:numbers are:234
    Function1: Number is 234
    two
    two hundred
    34Function2: Number is 34
    Function3: Number is 34
    Bus error: 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;
}

Answer

Sergey Kalinichenko picture Sergey Kalinichenko · May 24, 2012

The reason you are getting bus errors is because you are attempting to write into non-writable area (i.e. into the character constant, and also past the end of it); this is undefined behavior.

// 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!

The call to strcat tries to write into the terminating zero of string, and then continues writing past the end of the string constant. This is undefined behavior, so your program crashes.

To fix this problem, you need to copy " " into string, rather than assigning it to the string pointer.