I am getting a bus error in the following code
Asked Answered
L

1

6

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;
}
Lalapalooza answered 24/5, 2012 at 1:5 Comment(3)
Which line of code causes the bus error? Running it in a debugger should show you exactly which statement triggers the fault.Schafer
Welcome to StackOverflow. When you write the words "an error", it's very important that the very next thing you write is the exact error you're getting, including the error message you're seeing. We can't see your screen from here, and expecting everyone to try and compile/run your code just to find out what you're asking is very inconsiderate. If you want help here, you have to provide the information that will allow us to help you. Please take a few moments to review the FAQ, especially the part about how to ask questions here. Thanks. :)Inquisitor
The first thing you should do when your programs crashes (doesn't matter what kind of crash), is to run it in a debugger. It will help you pinpoint the location of the crash as well as let you examine variables to see what might have caused the crash.Ronaldronalda
L
5

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.

Lonnielonny answered 24/5, 2012 at 1:36 Comment(6)
Thanks for the reply. That makes sense a lot. But only confusion I am having right now is, if I enter 3 digit number like 234 as input then it works fine. I get the bus error only with I enter 4 digit numbers or more.Lalapalooza
@DangerousScholar This is because when you enter a number smaller than 1000, you hit the else branch, where string is assigned once more before you strcat into it. The assigned value is the dynamically allocated word from convert_number, which has enough memory past the end of the string for strcat to work without an error.Lonnielonny
Again, The debug message says the error should be between following code right? cout<<"Function3: Number is "<<number<<endl; if(number<20) { word=strcat(word,words[number]); word =strcat(word," "); } cout<<"Returning word:"<<word;Lalapalooza
@DangerousScholar Not necessarily: since you do not flush the buffer in the cout<<"Returning word:"<<word, bus error could prevent it from finishing a printout. Add endl at the end, and see if you get this debug output.Lonnielonny
Thanks so much, that solved the whole issue also I learned one more thing about flushing the buffer. Now I can work on the logic.Lalapalooza
@DangerousScholar If this issue is solved, consider accepting the answer by clicking the check mark outline next to it. This would indicate to others that you are not looking for a better solution, and earn you a brand-new badge on stack overflow.Lonnielonny

© 2022 - 2024 — McMap. All rights reserved.