这个问题现在让我大开眼界。
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;
}
现在如果我做了
cout << read(buffer);
在导致问题的那一行上,我收到一个整数...很棒,很完美。但如果我试着做
size = read(buffer);
我的程序崩溃了...我很茫然。
答案 0 :(得分:2)
您按值传递缓冲区(char *)。即使在read()例程中分配缓冲区,也会修改指针的本地副本。从read()返回时,仍然具有指针的旧的unititialized值,这是不可用的。要缓解此问题,您可以通过引用传递缓冲区。
答案 1 :(得分:2)
您正在按值传递变量(如果它是指针,则无关紧要)。在接收端,该函数制作传递内容的本地副本,使用本地副本和poof,当函数返回时本地副本消失。
无论您传递的是否是指针,都会发生这种情况。例如,请使用以下简单代码:
void foo(int x)
{
x = 10;
}
int main()
{
int val = 0;
foo(val);
cout << val; // how come val is still 0 and not 10?
}
请注意val
仍为0,即使该函数正在更改正在传递的参数。要解决此问题,请将引用传递给将要更改的值:
void foo(int& x)
{
x = 10;
}
int main()
{
int val = 0;
foo(val);
cout << val; // now val is 10
}
有了指针,规则就不会改变。您需要传递对指针的引用,以使更改反映回调用者:
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;
}
现在该函数中的buffer
不是本地副本,而是对您传递的变量的引用。
另一种方法(更多&#34; C&#34;样式)是将指针传递给你想要改变的东西。您想要更改指针值,因此您将指针传递给指针:
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);
当然,我们必须更改语法,因为它是一个正在传递的指针,因此我们需要取消引用它。
答案 2 :(得分:1)
我认为其他答案已经确定了您的编码错误。
我注意到你已将其标记为C ++ ...我建议如果使用C ++功能,可能不会发生错误。
我找到了以下内容(在SO和其他地方)。它是类似的,但依赖于经过强烈测试的std :: string内存管理,文件大小不需要额外的代码。
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());
}
某处你可能想要一个std :: char数组...请注意,缓冲区中有一个c样式的结果(以null结尾的字符串)。
您可以使用此技术加载任何大小的文本文件(适合您的内存)。