I wrote and run this code in Windows, in DEV C++ but I am keep getting a Segmentation fault on Ubuntu's terminal when I try to run this program. Here is my whole code.

#include<iostream>
#include<string>
#include<fstream>
#include<cmath>

using namespace std;

int Str2NumByAscii(const string& str); // convert string to number
                                       // by means of ascii table for
                                       // numbers 0-9 (ascii code: 48-57)
int* findRegister(string regreader1, string* regname, int* regadress[]);

void MOV(int* Rx, int* Ry);
void ADD(int* Rx, int* Ry);
void SUB(int* Rx, int* Ry);
void HLT(int* RegAdr[]);
void JMP(int *Rx, int number, int linenum,ifstream &read, string operation, string regreader1,string regreader2);

int main() {

    int R1=1,R2=2,R3=3,R4=4,R5=5;
  int* regadress[5]={&R1,&R2,&R3,&R4,&R5};
    string regname[5]={"R1","R2","R3","R4","R5"};

//  cout<<"Registered values before any operation\n";
//  HLT(regadress);

    string operation;//that string is for makin
  string regreader1;
  string regreader2;

    ifstream read;
    read.open("example.txt");

  int linenum = 0;
  string line;

     while (!read.eof()){
    getline(read, line);
    cout<<line<<endl;
    linenum++;
  }

  cout<<"total number of lines in file : " <<linenum<<endl;

  read.close();
  read.open("example.txt"); // for going the beginning of the file

  int current_line = 1; // keeps the number of current line
  while (!read.eof()){
    getline(read, operation,  ' ')  ;
    getline(read, regreader1, ',')  ;
    getline(read, regreader2, '\n') ;
    current_line++;

    int number;
    int* Rx = findRegister(regreader1,regname,regadress);

    int* Ry=findRegister(regreader2,regname, regadress);

if(!Ry) {
      number = Str2NumByAscii(regreader1);
      // call JMP function here
    }
    if(operation == "MOV"){
      MOV(Rx,Ry);
    }
    else if (operation == "ADD"){
      ADD(Rx,Ry);
    }
    else if(operation == "SUB"){
      SUB(Rx,Ry);
    }
  else if(operation== "JMP"){
    JMP(Rx,number,current_line, read, operation, regreader1,regreader2 );
  }
else if(operation=="HLT"){
    HLT(regadress);
    return 0;

}
  }
  cout<<"Registered values after any operation\n";
  HLT(regadress);
    return 0;

} // end of main()

int* findRegister( string regreader1, string* regname, int* regadress[] ){
  for(int i=0; i<5; ++i){
    if(regreader1==regname[i]){
      return regadress[i];
    }
  }
  return 0; // nullptr
}

int Str2NumByAscii(const string& str){
  int N = str.size();
  int number = 0 ;
  for(int i = 0; i < N; ++i ){
    char ch = str[i];
    int num = ch - 48;
    number += num * pow(10,N-i-1) ;
  }
  return number;
}

void MOV(int* Rx, int* Ry){
  *Rx = *Ry ;
}

void ADD(int* Rx, int* Ry){
  *Rx = *Rx + *Ry ;
}

void SUB(int* Rx, int* Ry){
  *Rx = *Rx - *Ry ;
}

void HLT(int* RegAdr[]){
  for(int i = 0 ; i < 5 ; ++i )
    cout<<*RegAdr[i]<<" ";
  cout<<"\n";

}
void JMP(int *Rx, int number, int linenum,ifstream &read, string operation, string regreader1,string regreader2){

if(Rx==0){
    while(number>=linenum && !read.eof()){
            getline(read, operation,  ' ')  ;
    getline(read, regreader1, ',')  ;
    getline(read, regreader2, '\n') ;

    }
}
}

/* example.txt
MOV R1,R2
SUB R1,R2
JMP R1,2
SUB R4,R5
HLT
*/

I am getting an segmentation fault about this function.

  int* findRegister( string regreader1, string* regname, int* regadress[] ){
      for(int i=0; i<5; ++i){
        if(regreader1==regname[i]){
          return regadress[i];
        }

Could you please help me ?

Dani AI

Generated

Most likely cause: you are dereferencing a null pointer returned by findRegister. This happens whenever an operand is not one of the defined register names (for example, your jump uses an immediate) or when tokenization fails and you end up with empty operands. On Linux this reliably triggers a segfault. Guard pointers before using them, and handle the no-operand instruction before trying to read two operands.

Example fixes you can apply immediately:

  • Parse per line, not with while(!read.eof()):

    for (std::string line; std::getline(read, line); ) {
        std::istringstream iss(line);
        std::string op, a, b;
        if (!(iss >> op)) continue;
        if (op == "HLT") { HLT(regadress); break; }
        std::getline(iss, a, ',');
        iss >> b;
    
        int* Rx = findRegister(a, regname, regadress);
        int* Ry = findRegister(b, regname, regadress);
    
        if (op == "JMP") {
            // Use the second operand for the target number
            int number = Ry ? *Ry : std::stoi(b);
            JMP(Rx, number, current_line, read, op, a, b);
            continue;
        }
    
        if (!Rx || !Ry) { std::cerr << "Invalid register\n"; continue; }
        // safe to call MOV/ADD/SUB now
    }
  • Replace the ASCII math with std::stoi and validate the string first.

  • Make findRegister take const std::string& and return nullptr explicitly; always check its result.

  • Build with sanitizers and warnings to pinpoint the exact line: -g -O0 -Wall -Wextra -fsanitize=address,undefined -fno-omit-frame-pointer.

Recommended Answers

All 2 Replies

Your code works properly on Ubuntu 16.04 compiled by CodeBlocks IDE 13.12

: CodeBlocks is a development UI that uses GCC under the covers to compile stuff. What compiler version are you running?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.