Reputation: 314
This problem is blowing my mind right now.
int main()
{
char inputChar;
char *buffer = nullptr;
int size = 0;
read(buffer); //this is the line causing problems...
int numberOfFrames = (size / MAX_FRAME_SIZE) + 1;
frame array[numberOfFrames];
for(int i = 0; i < size; i++)
{
buffer[i] = appendParityBit(buffer[i]);
}
constructFrame(buffer, size, array);
transmitFrames(array, numberOfFrames);
}
int read(char *buffer)
{
int fileSize;
ifstream myfile ("inputFile");
if (myfile.is_open())
{
fileSize = getFileLength(myfile);
buffer = new char[fileSize];
myfile.read(buffer, fileSize);
myfile.close();
}
return fileSize;
}
int getFileLength(ifstream &myfile)
{
myfile.seekg(0, ios::end);
int size = (int) myfile.tellg() - 1;
myfile.seekg(0, ios::beg);
return size;
}
now if i do a
cout << read(buffer);
on the line that is causing problems, i receive an integer back...great, perfect. but if i try to do
size = read(buffer);
my program crashes...i'm at a loss.
Upvotes: 0
Views: 1262
Reputation: 5566
I think the other answers have identified your coding error.
I note that you have tagged this as C++ ... and I suggest that perhaps your error would not have occurred if you used C++ features.
I have found the following (in SO and else where). It is similar, but relies on the strongly tested std::string memory management, and the file size requires no extra code on your part.
size_t read(std::string& buffer)
{
std::ifstream sIn("inputFile");
if (!sIn.is_open())
{
std::stringstream ssErr;
ssErr << "Can not open file '" << "inputFile" << "'" << std::endl;
throw ssErr.str();
}
std::stringstream ss(buffer);
ss << sIn.rdbuf(); // one line transfer of file contents
sIn.close(); // close sIn when we are done with it
if(sIn.bad())
throw "Err: sIn.rdbuf()";
return (ss.str().size());
}
Somewhere you might want a std::char array ... note that the c-style result (null terminated string) is available in buffer.c_str().
You can load any size text file (that fits in your memory) using this technique.
Upvotes: 1
Reputation: 35455
You are passing a variable by value (doesn't matter if it is a pointer or not). On the receiving end, the function makes a local copy of what is passed, works with the local copy, and poof, the local copy goes away when the function returns.
This occurs regardless of whether what you're passing is a pointer or not. For example, take this simple code:
void foo(int x)
{
x = 10;
}
int main()
{
int val = 0;
foo(val);
cout << val; // how come val is still 0 and not 10?
}
Note that val
is still 0, even though the function is changing the parameter that is being passed. To fix this problem, you pass a reference to the value that will be changed:
void foo(int& x)
{
x = 10;
}
int main()
{
int val = 0;
foo(val);
cout << val; // now val is 10
}
With pointers, the rules don't change. You need to pass a reference to the pointer to have the change reflect back to the caller:
int read(char*& buffer)
{
int fileSize;
ifstream myfile ("inputFile");
if (myfile.is_open())
{
fileSize = getFileLength(myfile);
buffer = new char[fileSize];
myfile.read(buffer, fileSize);
myfile.close();
}
return fileSize;
}
Now the buffer
in that function is not a local copy, but a reference to the variable you passed.
The other method (which is more "C" style) is to pass a pointer to the thing you want to change. You want to change the pointer value, so you pass a pointer to the pointer:
int read(char** buffer)
{
int fileSize;
ifstream myfile ("inputFile");
if (myfile.is_open())
{
fileSize = getFileLength(myfile);
*buffer = new char[fileSize];
myfile.read(buffer, fileSize);
myfile.close();
}
return fileSize;
}
// the caller
char *buffer;
//...
read(&buffer);
Of course, we have to change the syntax since it is a pointer that is being passed, thus we need to dereference it.
Upvotes: 2
Reputation: 62583
You are passing your buffer (char*) by value. Even when you allocate the buffer in your read() routine, this modifies local copy of the pointer. When you return from read(), you still have the old unititialized value of the pointer, which is not usable. To alleviate the issue, you can pass your buffer by reference.
Upvotes: 2