I have the following functions

void LoadData(char* file, float* data1, float* data2)
       // read data size and contents from file
      data1 = new float[dataSize1];
      data2 = new float[dataSize2];
      // store data
      data1[0] = 1.0f;
      data1[1] = 2.0f;
      // etc ...

void ComputeData()
      float *data1 = NULL;
      float *data2 = NULL;
      LoadData("file.txt", data1, data2);

      // on this line, data1 and data2 is still NULL;

Why doesn't the data pointers from ComputeData() point to the memory location?

How do I go about implementing LoadData() to output the arrays in the parameters?

Ok i found that if I modify the LoadData to

void LoadData(char* file, float*& data1, float*& data2)

Then it will work... this is the first time I'm seeing and using this. I never knew they need to be references. Any comments on efficiency or safety?

you have to use pointers to pointers (double stars)

const int dataSize1 = 5;
const int dataSize2 = 6;

void LoadData(char** file, float** data1, float** data2)
       // read data size and contents from file
       *file = new char[255];
       strcpy(*file, "This is a test");
      *data1 = new float[dataSize1];
      *data2 = new float[dataSize2];
      // store data
      (*data1)[0] = 1.0f;
      (*data2)[0] = 2.0f;
      // etc ...
int main()
    char *f1 = 0;
    float *f2 = 0, *f3 = 0;
    LoadData(&f1, &f2, &f3);
    cout << f1 << " " << f2[0] << " " << f3[0] << "\n";

Your original code is using pass-by-value. The value you're passing is a pointer (really an address) but your function still gets a copy of the pointer. So data1 and data2 inside the function are separate from data1 and data2 outside. Now you're changing data1 to point somewhere new, if you didn't do that it's value (which is an address) would be the same address as is in data1 outside. So any dereferences (* and [] operators) would hit the same data no matter whether you used data1 in the caller or the LoadData function. But as soon as you set data1 to some newly allocated memory in LoadData, it's no longer sharing anything with the data1 pointer in main.

Adding the & gives you pass-by-reference (which means LoadData's data1 is actually a pointer to ComputeData's data1, but the pointer aspect is all done automatically), so when you set data1 in LoadData it changes ComputeData's version (there is no copy).

The & for pass-by-reference is only available in C++, in plain C you'd do it the way Ancient Dragon says, with a double pointer (same thing, it points to ComputeData's data1).

Thanks a bunch. I failed to see it that way initiall because when data1 and data2 are global variables, they retain the memory location after coming out from LoadData().