T Y T Y - 3 months ago 21
C++ Question

Mysterious Segmentation Fault in C++ Code

It's been a while since I've coded C++ and I'm having some issues with this code sample:

#include <iostream>
#include <string>
#include <sstream>
#include <vector>

using namespace std;

string* data;
int current = 0;

void init(){
data = new string[6];
data[0] = "7 4 3";
data[1] = "8 11 12 16 17 18 20";
data[2] = "17 16 20 2 20 5 13";
data[3] = "17 8 8 16 12 15 13";
data[4] = "12 4 16 4 15 7 6";
data[5] = "8 14 2 11 17 12 8";
}

string getNext() {
if(current == 0){
init();
}
return data[current++];
}

void populate(int* target, int n){
target = new int[n];
string line = getNext();
stringstream ss(line);
for(int i=0; i<n; i++){
ss >> target[i];
cout << target[i] << endl;
}
// THIS WORKS FINE
for(int i=0; i<n; i++){
cout << "TARGET" << target[i] << endl;
}
}

int main() {
string line;
int n, s, e;
int* x, * a, * b, * c, *d;

line = getNext();
stringstream ss(line);
ss >> n >> s >> e;
cout << "N: " << n << " S: " << s << " E: " << e << endl;

populate(x, n);

// IMMEDIATE SEGMENTATION FAULT ON FIRST ITERATION
for (int i = 0; i < n; i++)
cout << x[i] << endl;
populate(a, n);
populate(b, n);
populate(c, n);
populate(d, n);

return 0;
}


In this program's final form, it will take user input, but for now I'm simulating input with an array of strings that I can read like I would read from cin.

I have several pointers for integer arrays that I'm going to dynamically allocate and fill in each with one line of string input.

I wrote the function
populate()
to do this for me so that I don't have too much duplicated code.

populate()
seems to load the data fine into the specified pointer. I can even print it back out before returning from the function.

HOWEVER, if I try to read the pointer AFTER
populate()
returns, I get an immediate segmentation fault. Any idea why? Is the reference being lost once the function returns? Do I have to convert the string chunks to ints explicitly in some manner? I'm a bit baffled by this.

GOT IT: been a while. Thank you!

Answer

Here's the culprit:

void populate(int* target, int n){
    target = new int[n];
    ...

Here you're passing target as int*, then immediately redefining it locally to the memory allocated, and the coupling to the pointer you passed in is lost. x is thus still unitialized inside main and accessing it is undefined behavior. Change the type of target to int*& and it should work for you. You may also use int** and pass the address of x, but this will required lots of changes to accessing target inside your function.

Comments