Search code examples
c++segmentation-faultstring-concatenation

SegFault while using std::string::operator+= with function as param


I understand that a Segmentation Fault occurs when there's a problem with insufficiently allocated memory/misdirection by pointers.

#include <iostream>
using namespace std;

const char *hex(char);

int main(int argc, char **argv)
{
    string url = "start http://www.cplusplus.com/search.do?q=";
    char a[2];

    for (int i = 0; i < argc; i++)
    {
        if (i != 1)
            url += '+';
        for (int j = 0; argv[i][j]; j++)
        {
            if (i == 1 && j == 0 && argv[i][j] == '.')
                continue;
            url += '%';

            // a[0] = argv[i][j] / 16;
            // a[1] = argv[i][j] % 16;
            // for (int k = 0; k < 2; k++)
            // {
            //  if (a[k] > 9)
            //      a[k] += 'A' - 10;
            //  else
            //      a[k] += '0';
            //  url += a[k];
            // }

            url += hex(argv[i][j]);
        }
    }
    system(url.c_str());
    return 0;
}

const char *hex(char c)
{
    char h = {c / 16, c % 16, '\0'};
    for (int k = 0; k < 2; k++)
        if (h[k] > 9)
            h[k] += 'A' - 10;
        else
            h[k] += '0';
    return h;
}

But for this piece of code, which is expected to work like a command for url encoding the arguments passed, there's a problem with the operator += for string class. I have followed it in the debugger and the function hex works properly(returns hexValue of char c).

But at this line, url += hex(argv[i][j]); there's a segFault for some reason, argv[i][j] is char and hex() returns its hex value in form of const cstring (const char *). I even added a null character at the end, if it made any difference...

I have even checked the std::string reference to make sure that operator accepts const char* (but that's obvious, otherwise there would be Compile-t errors, which I had none).

Any guesses? btw, the commented code is substitute for the function-style code and works flawlessly, on Windows of course.

Any suggestion is much appreciated, coz if this function works, it would make this bit extra portable, I know there might be library functions for url encoding but this is just practice.


Solution

  • Your hex function is returning an address to a temporary local variable, which is a huge problem, so it crashes there when that memory gets re-used.

    When that function returns h falls out of scope immediately, so any pointers to h are invalidated.

    Since you're using C++, just use std::string:

    std::string hex(const char c)
    {
        std::string h = {c / 16, c % 16, '\0'};
    
        for (int k = 0; k < 2; k++)
            if (h[k] > 9)
                h[k] += 'A' - 10;
            else
                h[k] += '0';
    
        return h;
    }
    

    Also instead of reinventing the wheel, consider using things like std::hex to do this for you as demonstrated here.