-3

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.

makeway4pK
  • 11
  • 3
  • 1
    The "some reason" part is why you drop this into your debugger to find out exactly where it crashes, then run it again and step carefully up to that point while observing the behaviour of your code and the state of any relevant variables. – tadman Oct 17 '18 at 17:15
  • I'm really confused by your `hex` implementation. It is declared to return `const char*` but you return a `char`. The char `h` is initialized with an initializer list as though it were an array. I'm astonished that this apparently compiles. Have you muted your compiler warnings? – alter_igel Oct 17 '18 at 17:17
  • Indeed, your `hex` function [**does not compile**](http://coliru.stacked-crooked.com/a/f3cfe25ae036182f). – alter_igel Oct 17 '18 at 17:20

1 Answers1

1

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.

tadman
  • 208,517
  • 23
  • 234
  • 262
  • So, does this mean that it's impossible to return a cstring from a c++ function? I'm confused. I'm just a beginner and want to understand the basics, by trying dumb things like these – makeway4pK Oct 17 '18 at 17:29
  • @user10519731 it's completely possibly, since C++ is mostly a superset of C. However, C-style strings force you to think about lifetime and ownership and resource management. C++'s `std::string` can be used simply, safely, and correctly without thinking about any of those. – alter_igel Oct 17 '18 at 17:30
  • You can return a C-style string *if and only if* you dynamically allocate it (e.g. `malloc`), or it existed or was otherwise allocated *before* the function. If you dynamically allocate it's the responsibility of the caller of this function to eventually free it up (e.g. `free`). As C forces you to understand memory management at an extremely low level, it's usually best to avoid all that and use C++ containers like `std::vector` and `std::string` whenever possible. These are usually quick and cheap to copy, and can use references to optimize how data is stored and persisted. – tadman Oct 17 '18 at 17:33
  • @DanielSchepler Technically true, also super dangerous. Some knowledge should be retained and not dispensed until it's absolutely necessary. – tadman Oct 17 '18 at 18:06