-1

I have a problem where I cannot print out the pointer outside the function.

This is what I have in my int main(), where I've created 2 pointers to pass into the function extractRange.

if(i == 0)
{
    int *x, *y;
    extractRange(grid[i], x, y);
    cout << x << endl << y << endl; // will cout the address
    cout << *x << endl << *y; // crash here and show segmentation fault (core dumped) error     
}

This is my extractRange function:

void extractRange(string line, int *start, int *end)
{   
    int x, y;
    int pos = 0;

    for (; pos < line.length(); pos++ )
    { 
        if ( isdigit(line[pos])) 
            break; 
    }

    line = line.substr(pos, line.length() - pos);
    x = atoi(line.c_str());

    pos = line.find("-"); 
    line = line.substr(pos + 1); 
    y = atoi(line.c_str());

    start = &x;
    end = &y;

    cout << *start << endl; // able to cout the int 0
    cout << *end << endl;   // able to cout the int 8
}

How come I am able to cout out the value of start and end inside the function but not outside the function?

Benjan
  • 21
  • 1
  • 7
  • You need references to modify parameter: `int *start` --> `int *&start` – Kostas Jan 20 '20 at 04:05
  • Don't create pointers in `main()`, declare `x, y` as `int` and just return the value of `x` and `y` through the pointers `start` and `end` by updating the value at the address for `start` and `end`, e.g. `*start = w;` and `*end = y;`. Then `start` and `end` make the values available back in the caller. (as shown in the answer by TruthSeeker) – David C. Rankin Jan 20 '20 at 04:23
  • @Kostas not a great solution as the code would then set the argument pointers to be dangling – M.M Jan 20 '20 at 05:06
  • @M.M Do you mean because they are not initialized before function call? Would setting them to null originally work? – Kostas Jan 20 '20 at 14:41
  • @Kostas no; after the function returns the pointers will point to stack objects that no longer exist – M.M Jan 20 '20 at 21:52
  • @M.M Oh, right. Totally missed that – Kostas Jan 20 '20 at 22:12

2 Answers2

1

As x and y are local to a function extractRange and allocated on stack, once the function is exited both variable seize to exist. start and end pointing to local variables can print the actual data when it is in function scope. Once the function scope is exited these two pointers will become dangling pointers and causes undefined behavior.

Pass the address of local variables instead pointer to the function. Something like below,

int x,y;
extractRange(grid[i], &x, &y);//pass the address of x and y
std::cout<<x<<" "<<y<<std::endl

within function body

void extractRange(string line, int *start, int *end)
{   
   //...

    *start = x;//assign value not a pointer
    *end = y;//assign value not a pointer
}

And rest all remains unchanged

TruthSeeker
  • 1,539
  • 11
  • 24
0

It would be better to return the return values instead of trying to use a legacy hack from 1970s C :

auto extractRange(string line)
{   
    int x, y;

    // ...logic to assign x and y .../

    return std::tuple{x, y};
}

And in the calling context:

auto [x, y] = extractRange(grid[i]);
M.M
  • 138,810
  • 21
  • 208
  • 365