当方法返回值分配给int时,C ++程序崩溃

时间:2015-09-21 21:48:02

标签: c++

这个问题现在让我大开眼界。

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);  

我的程序崩溃了...我很茫然。

3 个答案:

答案 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结尾的字符串)。

您可以使用此技术加载任何大小的文本文件(适合您的内存)。