Marcelo
Marcelo

Reputation: 824

Getting segmentation fault on function

I have got this function which converts a month from 3 chars to 2 digits month:

int Extract_Month(char *pDestMonth, char *pMonth)
{
    char monthschar[12][4] = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };
    char monthsdigit[12][3] = { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12" };
    int i = 0;

char tmpStr[4] = "";
tmpStr[0] = (pMonth[0] >= 'a' && pMonth[0] <= 'z') ? ('a' + pMonth[0] - 'A') : pMonth[0];
tmpStr[1] = (pMonth[1] >= 'a' && pMonth[1] <= 'z') ? ('a' + pMonth[1] - 'A') : pMonth[1];
tmpStr[2] = (pMonth[2] >= 'a' && pMonth[2] <= 'z') ? ('a' + pMonth[2] - 'A') : pMonth[2];
tmpStr[3] = 0;

for (i = 0; i < 12; i++)
{
    if (!strncmp(tmpStr, monthschar[i], 3))
    {
        StrMove((uchar *)pDestMonth, (uchar *)monthsdigit[i], 2);
        return 0;
    }
}
return -1;
}

I am running it with gdb and I'm getting a segmentation fault error. Does anyone knows what am i missing here?

I have made some research and I found that seg faults are due to memory mishandling.

gdb output points exactly to this function declaration

This is where the function is being called (reduced code): enter image description here

Upvotes: 0

Views: 128

Answers (2)

darune
darune

Reputation: 10962

You are making something really simple in an extremely complicated way..

Since you flagged it , you can just use a map and return by lookup like this:

std::string Extract_Month_As_Digits(const std::string& month)
{
  static std::map<std::string, std::string> monthToDigit = {{"JAN", "01"}};//omitted init.
  auto found = monthToDigit.find(month);
  return found  != monthToDigit.end() ? *found : "";
}

If you want an exception thrown on bad input/lookup, you may reduce it to return monthToDigit.at(month);

Upvotes: 5

xtofl
xtofl

Reputation: 41509

You're making it very complex. Simplifying the solution may result in a function that does no strcpy whatsoever:

int month_index(const char *threeDigitMonth) {
    static const char *names[] = {"JAN", "FEB", NULL};
    const char** name = names;
    while(name && strcmp(threeDigitMonth, *name)){ ++name; }
    return name - names;
}

Now your problem is reduced to converting an int into a two-digit string, something snprintf is very capable of.

Or you could use C++:

auto month_index(const std::string& threeDigitMonth) {
  static const std::unordered_map<
     std::string, std::string> months = {{
       {"JAN", "01"},
       {"FEB", "02"},
       ...
    }};
    return months.at(threeDigitMonth);
  }

Upvotes: 1

Related Questions