-1

Here i have a code that translates numerical characters into roman literals, the following code works for little value smaller than 3 digits, it was supposed to work until 4 digits, when numbers are greater than 1000 it returns a segmentation fault exception. What are segmentation faults and how to avoid them

#include <unordered_map>
#include <iterator>
#include <iostream>
#include <vector>
using namespace std;
int quotient(int nominator, int denominator);
string solution(int number){
 std::unordered_map<int,string> Configuration;
 std::string result;
 int multimes=0;
 string character;
 Configuration[1000]="M";
 Configuration[500]="D";
 Configuration[100]="C";
 Configuration[50]="L";
 Configuration[10]="X";
 Configuration[5]="V";
 Configuration[1]="I";
 vector<int> NumConfig={1000,500,100,50,10,5,1};
 for(vector<int>::iterator it=NumConfig.begin();it!=NumConfig.end();++it)
 {
   multimes=quotient(number,*it); 
   number-=multimes* (*it);
   character=Configuration.find(*it)->second;
   int var=0;
   if(multimes>0 && multimes<=3 ){
   while(var < multimes)
   {
     result.append(character);
     var++;
   }}
   else if(multimes>3)
   {
     result.append(Configuration.find(*it-1)->second);
     result.append(character);
   }
 }
 return result;
}
int quotient (int nominator,int denominator)
{
    int result=(int)nominator/denominator;
    return result;
}
int fromint (istream &str){int x;str>>x;return x;}
int main()
{
    while(true)
    {
        cout<<solution(fromint(cin));
    }
    return 0;
}
Rhathin
  • 1,176
  • 2
  • 14
  • 20
MyDoom
  • 37
  • 1
  • 6
  • https://stackoverflow.com/questions/2346806/what-is-a-segmentation-fault – rustyx Dec 27 '19 at 08:35
  • 1
    A "segmentation fault" means that your host (unix variant) operating system detected your program accessing memory it shouldn't. The OS then sends a signal to your program that forces it to terminate. There are many possible ways for a program to access memory it shouldn't, such as accessing array elements out of bounds (e.g. accessing the tenth element of a 5-element array), dereferencing a NULL pointer, etc etc. There are so many ways, that it is impossible to give a simple recipe to prevent it happening. – Peter Dec 27 '19 at 08:39
  • 1
    I imagine `Configuration.find(*it-1)` is returning `Configuration.end()`, if you run your code inside gdb it'll tell you for sure – Alan Birtles Dec 27 '19 at 08:45
  • Looks like it's time to learn [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems). – Lukas-T Dec 27 '19 at 08:57

2 Answers2

1

try use debug tools such as assert, put it preceding any pointer assignment to guard it

// ...
for(vector<int>::iterator it=NumConfig.begin();it!=NumConfig.end();++it){
  assert( it != nullptr );

  // ...
}

if a pointer prepared in such guard is violated ie. the boolean result is false then:

assertion "it != nullptr" failed: file " ....

  • You will never get this assert because in the case of an empty array, the for is not executed. So, this is not an answer. – mr NAE Dec 27 '19 at 13:32
1

I could see the segmentation fault when input is equals to (5n -1)(i.e 4,9,14...) , where n is any natural number. Configuration.find(*it - 1) returning Configuration.end()

avoid segmentation fault by explicit check for Configuration.end()

EDIT

*it-1 which is subtracting *it value by one instead pointing to previous value from Configuration. You can change it to *(it-1) to avoid fragmentation error.

TruthSeeker
  • 1,539
  • 11
  • 24