CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8

Hybrid View

  1. #1
    Join Date
    Feb 2010
    Posts
    3

    [RESOLVED] Segmentation Fault?

    I am trying to build an Assembler in C++, but when I return from a function (itoa), I get a seg. fault before I can print anything out. The output makes it obvious that the issue is between the end of the function and the next line of code in the calling function. I have tried returning std::string and std::string* instead of doing parameters by reference, but nothing has worked. I have no clue where it is coming from, so any help on where to look would be great. Below is the relevant code and output:

    void Assembler::assembleCode(std::string assembly) {
    ...
    std::string imm;
    std::cout << "14\n";
    itoa(labelPositions[tokens[3]], 16, imm);
    std::cout << "13\n";
    ...
    }

    void Assembler::itoa(int value, int len, std::string& imm) {
    ...
    imm = std::string(binresult.substr(30 - len, len));
    std::cout << "Translated to " << imm << std::endl;
    }

    Output:
    ....
    14
    ....
    Translated to 0000000000011111
    Segmentation Fault

  2. #2
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Segmentation Fault?

    Valgrind it and report the results.

    Also, the actual problem might be elsewhere in the code; perhaps it just didn't cause any trouble until there.

  3. #3
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,721

    Re: Segmentation Fault?

    I am not familiar with itoa, but I doubt that it can take a std::string
    as a parameter.

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Segmentation Fault?

    Quote Originally Posted by davidov541 View Post
    I am trying to build an Assembler in C++, but when I return from a function (itoa), I get a seg. fault before I can print anything out. The output makes it obvious that the issue is between the end of the function and the next line of code in the calling function. I have tried returning std::string and std::string* instead of doing parameters by reference, but nothing has worked. I have no clue where it is coming from, so any help on where to look would be great. Below is the relevant code and output:
    Don't hide code using "...". That code you're not showing us could be the reason why you are having problems.
    Code:
    itoa(labelPositions[tokens[3]], 16, imm);
    tokens[3] is what value? What is labelPositions? Is labelPositions[token[3]] valid?
    Code:
    imm = std::string(binresult.substr(30 - len, len));
    he value of binresult before the substr is what?

    Basically, no one can know what you have without real code and real values to deal with.

    Also, if all you're doing is trying to translate an integer to a binary string, std::bitset does that already.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; February 27th, 2010 at 08:01 PM.

  5. #5
    Join Date
    Feb 2010
    Posts
    3

    Re: Segmentation Fault?

    Here is the actual code. I thought it was too much code for you guys to have to sift through, so I didn't originally show it. The portions that the code came from are mostly in the beginning and end of the functions.

    void Assembler::assembleCode(std::string assembly) {
    std::stringstream ss;
    std::vector<std::string> instructions;
    boost::split(instructions, assembly, boost::is_any_of("\n"));
    int pos = 1;
    std::vector<std::string> actualInstructions = std::vector<std::string>(instructions.size());
    boost::unordered_map<std::string, int> labelPositions;
    BOOST_FOREACH(std::string inst, instructions) {
    if (inst[0] == '#' || inst[0] == ' ' || inst[0] == '\n') {
    continue;
    }
    std::vector<std::string> nonLabels;
    boost::split(nonLabels, inst, boost::is_any_of(":"));
    if (nonLabels.size() > 1) {
    labelPositions[nonLabels[0]] = pos;
    actualInstructions[pos - 1] = nonLabels[1];
    } else {
    actualInstructions[pos - 1] = nonLabels[0];
    }
    pos++;
    }
    std::vector<std::string>::iterator itr;
    for(int i = 0; i < actualInstructions.size(); i++) {
    std::cout << "12\n";
    std::string inst = actualInstructions[i];
    std::cout << "Evaluating Instruction: ";
    std::cout << inst << std::endl;
    std::vector<std::string> tokens;
    boost::split(tokens, inst, boost::is_any_of(", "));
    if (tokens.size() > 0) {
    boost::trim(tokens[0]);
    std::string instructionCode;
    if (tokens[0].compare("j") == 0) {
    boost::trim(tokens[1]);
    std::string imm;
    itoa(labelPositions[tokens[1]], 11, imm);
    ss << "\n00000" << imm;
    } else if (tokens[0].compare("jal") == 0) {
    boost::trim(tokens[1]);
    std::string imm;
    itoa(labelPositions[tokens[1]], 11, imm);
    ss << "\n00001" + imm;
    } else if (tokens[0].compare("jr") == 0) {
    boost::trim(tokens[1]);
    ss << "\n00010" + translateRegister(tokens[1]) + "0000000\n";
    } else if (tokens[0].compare("nop") == 0) {
    ss << "\n0001100000000000";
    } else if (tokens[0].compare("move") == 0) {
    boost::trim(tokens[1]);
    boost::trim(tokens[3]);
    ss << "\n00100" << translateRegister(tokens[1]) << translateRegister(tokens[3]) << "000";
    } else if (tokens[0].compare("ldi") == 0) {
    boost::trim(tokens[1]);
    boost::trim(tokens[3]);
    std::string imm;
    itoa(atoi(tokens[3].c_str()), 16, imm);
    ss << "\n00101" << translateRegister(tokens[1]) << "0000000\n" << imm;
    } else if (tokens[0].compare("neg") == 0) {
    boost::trim(tokens[1]);
    boost::trim(tokens[3]);
    ss << "\n00110" << translateRegister(tokens[1]) << translateRegister(tokens[3]) << "000";
    } else if (tokens[0].compare("not") == 0) {
    boost::trim(tokens[1]);
    boost::trim(tokens[3]);
    ss << "\n00111" << translateRegister(tokens[1]) << translateRegister(tokens[3]) << "000";
    } else if (tokens[0].compare("mfc0") == 0) {
    boost::trim(tokens[3]);
    boost::trim(tokens[1]);
    ss << "\n01000" << translateRegister(tokens[1]) << translateRegister(tokens[3]) << "000";
    } else if (tokens[0].compare("mtc0") == 0) {
    boost::trim(tokens[1]);
    boost::trim(tokens[3]);
    ss << "\n01001" << translateRegister(tokens[1]) << translateRegister(tokens[3]) << "000";
    } else if (tokens[0].compare("rdr") == 0) {
    boost::trim(tokens[1]);
    ss << "\n01010" << translateRegister(tokens[1]) << "0000000";
    } else if (tokens[0].compare("wdr") == 0) {
    boost::trim(tokens[1]);
    ss << "\n01011" << translateRegister(tokens[1]) << "0000000";
    } else if (tokens[0].compare("addi") == 0) {
    boost::trim(tokens[1]);
    boost::trim(tokens[3]);
    std::string imm;
    itoa(atoi(tokens[3].c_str()), 7, imm);
    ss << "\n01100" << translateRegister(tokens[1]) << imm;
    } else if (tokens[0].compare("nori") == 0) {
    boost::trim(tokens[1]);
    boost::trim(tokens[3]);
    std::string imm;
    itoa(atoi(tokens[3].c_str()), 7, imm);
    ss << "\n01101" << translateRegister(tokens[1]) << imm;
    } else if (tokens[0].compare("add") == 0) {
    boost::trim(tokens[1]);
    boost::trim(tokens[3]);
    ss << "\n01110" << translateRegister(tokens[1]) << translateRegister(tokens[3]) << "000";
    } else if (tokens[0].compare("and") == 0) {
    boost::trim(tokens[1]);
    boost::trim(tokens[3]);
    ss << "\n01110" << translateRegister(tokens[1]) << translateRegister(tokens[3]) << "001";
    } else if (tokens[0].compare("or") == 0) {
    boost::trim(tokens[1]);
    boost::trim(tokens[3]);
    ss << "\n01110" << translateRegister(tokens[1]) << translateRegister(tokens[3]) << "010";
    } else if (tokens[0].compare("sll") == 0) {
    boost::trim(tokens[1]);
    boost::trim(tokens[3]);
    std::string imm;
    itoa(atoi(tokens[3].c_str()), 7, imm);
    ss << "\n01110" << translateRegister(tokens[1]) << imm;
    } else if (tokens[0].compare("bgt") == 0) {
    boost::trim(tokens[1]);
    boost::trim(tokens[3]);
    boost::trim(tokens[5]);
    ss << "\n1000" << translateRegister(tokens[1]) << translateRegister(tokens[3]) << translateRegister(tokens[5]);
    } else if (tokens[0].compare("blt") == 0) {
    boost::trim(tokens[1]);
    boost::trim(tokens[3]);
    boost::trim(tokens[5]);
    ss <<"\n1001" << translateRegister(tokens[1]) << translateRegister(tokens[3]) << translateRegister(tokens[5]);
    } else if (tokens[0].compare("beq") == 0) {
    boost::trim(tokens[1]);
    boost::trim(tokens[3]);
    boost::trim(tokens[5]);
    ss << "\n1010" << translateRegister(tokens[1]) << translateRegister(tokens[3]) << translateRegister(tokens[5]);
    } else if (tokens[0].compare("bne") == 0) {
    boost::trim(tokens[1]);
    boost::trim(tokens[3]);
    boost::trim(tokens[5]);
    ss << "\n1011" << translateRegister(tokens[1]) << translateRegister(tokens[3]) << translateRegister(tokens[5]);
    } else if (tokens[0].compare("rp") == 0) {
    boost::trim(tokens[1]);
    ss << "\n1100" << translateRegister(tokens[1]) << "00000000";
    } else if (tokens[0].compare("lwn") == 0) {
    boost::trim(tokens[1]);
    boost::trim(tokens[3]);
    boost::trim(tokens[5]);
    ss << "\n1110" << translateRegister(tokens[1]) << translateRegister(tokens[3]) << translateRegister(tokens[5]);
    } else if (tokens[0].compare("swn") == 0) {
    boost::trim(tokens[1]);
    boost::trim(tokens[3]);
    boost::trim(tokens[5]);
    ss << "\n1111" << translateRegister(tokens[1]) << translateRegister(tokens[3]) << translateRegister(tokens[5]);
    } else if (tokens[0].compare("la") == 0) {
    boost::trim(tokens[1]);
    boost::trim(tokens[3]);
    std::string imm;
    std::cout << "14\n";
    itoa(labelPositions[tokens[3]], 16, imm);
    std::cout << "13\n";
    ss << "\n00101" << translateRegister(tokens[1]) << "0000000\n" << imm;
    std::cout << "10\n";
    }
    }
    std::cout << "11\n";
    }
    this->machineCodeVal = ss.str();
    std::cout << this->machineCodeVal;
    std::cout << "4\n";
    }

    void Assembler::itoa(int value, int len, std::string& imm) {
    char* octresult;
    std::cout << "Translating " << value << std::endl;
    sprintf(octresult, "%10o", value);
    std::string octresultstr = std::string(octresult);
    std::string binresult;
    for(int i = 0; i < octresultstr.size(); i++) {
    switch(octresult[i]) {
    case '0':
    binresult = binresult + "000";
    break;
    case '1':
    binresult = binresult + "001";
    break;
    case '2':
    binresult = binresult + "010";
    break;
    case '3':
    binresult = binresult + "011";
    break;
    case '4':
    binresult = binresult + "100";
    break;
    case '5':
    binresult = binresult + "101";
    break;
    case '6':
    binresult = binresult + "110";
    break;
    case '7':
    binresult = binresult + "111";
    break;
    case ' ':
    if (value < 0) {
    binresult = binresult + "111";
    } else {
    binresult = binresult + "000";
    }
    break;
    default:
    binresult = binresult + "xxx";
    break;
    }
    }
    imm = std::string(binresult.substr(30 - len, len));
    std::cout << "Translated to " << imm << std::endl;
    }

    Also, in response to the other question, itoa is a function that comes with C++ in windows, but I rewrote in order to make it work in Linux.

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Segmentation Fault?

    Quote Originally Posted by davidov541 View Post
    Here is the actual code. I thought it was too much code for you guys to have to sift through,
    That's the point. Your code is much bigger than what you posted, and therefore the problem can stem from anywhere within this large portion of code.
    Code:
    char* octresult;
    std::cout << "Translating " << value << std::endl;
    sprintf(octresult, "&#37;10o", value);
    That sprintf is copying to an uninitialized pointer "octresult". Therefore you are writing to who-knows-where, possibly corrupting memory.

    Also, please re-edit your post to use code tags. The code you wrote is unreadable without code tags.
    Code:
         void Assembler::assembleCode(std::string assembly) {
    	std::stringstream ss;
    	std::vector<std::string> instructions;
    	boost::split(instructions, assembly, boost::is_any_of("\n"));
    	int pos = 1;
    	std::vector<std::string> actualInstructions =
    That is an example of usage of code tags.
    Also, in response to the other question, itoa is a function that comes with C++ in windows, but I rewrote in order to make it work in Linux.
    But why not use std::bitset::to_ulong() to convert from an integer to a string of binary digits? You even are using boost, and that has a dynamic bitset class. A lot of that code that seemingly is translating an int to binary is already taken care of by the above mentioned classes.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; February 27th, 2010 at 09:01 PM.

  7. #7
    Join Date
    Feb 2010
    Posts
    3

    Re: Segmentation Fault?

    Changing over to the bitset solution worked out well. Thank you for your help. Sadly, the library is hard to find (I had to explicitly look up the library you mentioned, I couldn't find it just googling the problem). Hopefully this finally fixes the rest of my issues with the program.

  8. #8
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Segmentation Fault?

    Quote Originally Posted by davidov541 View Post
    Also, in response to the other question, itoa is a function that comes with C++ in windows, but I rewrote in order to make it work in Linux.
    Since you're using std::string anyway, just use stringstreams to do conversions to/from strings. Or, if you have access to boost, a boost::lexical_cast will work as well. There's no need to re-write a function when there are other alternatives available which do the same thing. Even an sprintf() would work.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured