与main.cpp以外的文件中定义的结构的奇怪性

时间:2010-07-19 10:11:51

标签: c++ struct

我发现在一个单独的Cpp文件中定义了一个结构(带有一个双精度数组和一个整数数组),但是从main调用的结果将不合理的值发送到cout的数组。低于我希望的最小例子,以及控制台输出。

道歉我的代码应该被扰乱 - 我一直在努力格式化它。

如果有人能帮助我理解并纠正这一点,我将不胜感激。

最好,乔

(1)main.cpp:

#include "iostream"
#include "defs.h"

using namespace std;

int main()
{
    MyStruct myModel=ConstructModel();

    cout << endl << "myModel goes first:" << endl;
    for(int i=0; i<myModel.n; i++)
        cout << "myModel.Y[" << i << "]=" << myModel.Y[i] << endl;
    cout << "myModel.n=" << myModel.n << endl;

    MyStruct myOtherModel;
    myOtherModel.n=2; double Y[2]={0.1,0.1};
    myOtherModel.Y=Y;

    cout << endl << "now myOtherModel:" << endl;
    for(int i=0; i<myModel.n; i++)
        cout << "myOtherModel.Y[" << i << "]=" << myOtherModel.Y[i] << endl;

    return 0;
}

(2)defs.cpp:

#include "defs.h"

MyStruct ConstructModel()
{
 MyStruct Model;

 double Y[2]={0.1,0.1}; Model.Y=Y;
    int n=2; Model.n=n;

    return Model;
}

(3)defs.h:

#ifndef DEFS_H  
#define DEFS_H

struct MyStruct
{
    double *Y;//length (n+1)
    int n;
};

MyStruct ConstructModel();

#endif

控制台输出

在我的机器上(WinXP 32bit,MSVC2008),这给出了:

myModel是第一位的:

myModel.Y [0] = 1.12947e-307

myModel.Y [1] = 1.80243e-307

myModel.n = 2

现在是myOtherModel:

myOtherModel.Y [0] = 0.1

myOtherModel.Y [1] = 0.1

5 个答案:

答案 0 :(得分:10)

你的struct包含一个指向双精度的裸指针。在defs.cpp中,您将其初始化为局部变量。在ConstructModel()范围之外,该内存不再有效。

如果你想在一个结构中使用一个数组,你必须声明它(包括它的大小,然后所有MyStruct的大小必须相同)。但不是使用数组,为什么不使用例如std::list<double>std::vector<double>

答案 1 :(得分:2)

问题是Y中包含的数组ConstructModel仅在执行ConstructModel时才有效。你(间接地)传回一个指向这个局部变量的指针,这个局部变量在被访问时不再有效。

答案 2 :(得分:2)

MyStruct ConstructModel()
{
  MyStruct Model;

  double Y[2]={0.1,0.1}; 

此处您将本地Y[0]的地址指定给Model.Y

  Model.Y=Y;
  int n=2; 
  Model.n=n;

  return Model;

此处本地Y超出范围并被销毁,Model.Y指向不存在的对象:

}

答案 3 :(得分:1)

当ConstructModel函数完成时,数组超出范围。尝试在堆上创建数组。

答案 4 :(得分:0)

这不是答案,而是上面的另一个问题。

如果我将代码更改为如下所示,当结构只包含这一个指针时,指针似乎不会超出范围。如果结构被定义为包含另一个值(例如,整数),则地址将丢失。难道这似乎没有表明对我的第一个问题的解释不完整吗?

我不确定这对任何人是否有任何兴趣。我怀疑声明和定义/分配结构的内部导致这种现象 - 也许有人可以确认/解释。

#include "iostream"
using namespace std;

struct MyStruct
{
    //int n; // <-- if commented, result is as expected. Else, address is lost.
    double *Y;//length (n+1)
};

MyStruct ConstructModel()
{
    MyStruct Model;
    //int n=2; Model.n=n;
    double Y[2]={0.1,0.1}; Model.Y=Y;
    return Model;
}


int main()
{
    MyStruct myModel=ConstructModel();

    for(int i=0; i<2; i++)
        cout << "myModel.Y[" << i << "]=" << myModel.Y[i] << endl;

    return 0;
}

更新:使用g ++而不是MSVC进行编译并不会显示输出的差异。因此似乎是编译器特定的......