简体   繁体   English

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

[英]Oddity with structs defined in files other than main.cpp

I have found that a struct (with an array of doubles and one integer) defined in a separate Cpp-file, but called from main sends unreasonable values to cout for the array. 我发现在一个单独的Cpp文件中定义了一个结构(带有一个双精度数组和一个整数数组),但是从main调用的结果将不合理的值发送给cout用于数组。 Below what I hope to be a minimum example, along with the console output. 下面我希望是最小的例子,以及控制台输出。

My apologies should my code be scrambled -- I have been struggling a bit with formatting it properly. 我的道歉应该是我的代码被扰乱 - 我一直在努力格式化它。

I'd be grateful if someone could help me understand and rectify this. 如果有人能帮助我理解并纠正这一点,我将不胜感激。

Best, Jo 最好,乔

(1) main.cpp: (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: (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: (3)defs.h:

#ifndef DEFS_H  
#define DEFS_H

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

MyStruct ConstructModel();

#endif

Console output 控制台输出

On my machine (WinXP 32bit, MSVC2008), this gives: 在我的机器上(WinXP 32bit,MSVC2008),这给出了:

myModel goes first: myModel排在第一位:

myModel.Y[0]=1.12947e-307 myModel.Y [0] = 1.12947e-307

myModel.Y[1]=1.80243e-307 myModel.Y [1] = 1.80243e-307

myModel.n=2 myModel.n = 2

now myOtherModel: 现在myOtherModel:

myOtherModel.Y[0]=0.1 myOtherModel.Y [0] = 0.1

myOtherModel.Y[1]=0.1 myOtherModel.Y [1] = 0.1

Your struct contains a naked pointer to doubles. 你的struct包含一个指向双精度的裸指针。 In defs.cpp, you're initializing that to a local variable. 在defs.cpp中,您将其初始化为局部变量。 Outside the scope of ConstructModel() , that memory is no longer valid. ConstructModel()范围之外,该内存不再有效。

If you want an array in a struct, you have to declare it (including its size, which then has to be the same for all MyStruct s). 如果你想在一个struct中使用一个数组,你必须声明它(包括它的大小,然后必须对所有MyStruct都相同)。 But rather than using arrays, why don't you use eg std::list<double> or std::vector<double> ? 但是,为什么不使用例如std::list<double>std::vector<double>

The problem is that the array Y contained in ConstructModel is only valid for as long as ConstructModel is being executed. 的问题是,在阵列Y包含在ConstructModel仅适用于只要ConstructModel正在执行。 You're (indirectly) passing back a pointer to this local variable, which is no longer valid by the time it's being accessed. 您(间接)传回一个指向此局部变量的指针,该局部变量在被访问时不再有效。

MyStruct ConstructModel()
{
  MyStruct Model;

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

here you assign the address of the local Y[0] to Model.Y : 在这里你将本地Y[0]的地址分配给Model.Y

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

  return Model;

here the local Y goes out of scope and is destroyed, leaving Model.Y with a pointer to a non-existing object: 这里局部Y超出范围并被销毁,使Model.Y具有指向不存在对象的指针:

}

When the function ConstructModel finishes the array gets out of scope. 当ConstructModel函数完成时,数组超出范围。 Try creating array on the heap. 尝试在堆上创建数组。

It's not an answer, but yet another question on back of the above. 这不是答案,而是上面的另一个问题。

If I change the code to the below, the pointer does not seem to go out of scope when the struct only consists of this one pointer. 如果我将代码更改为如下所示,当结构只包含这一个指针时,指针似乎不会超出范围。 If the struct is defined to contain another value (say, an integer), the address is lost. 如果结构被定义为包含另一个值(例如,整数),则地址将丢失。 Doesn't this seem to suggest that the explanations to my first question are not the full picture? 难道这似乎没有表明对我的第一个问题的解释不完整吗?

I'm not sure if this is of any interest to anyone. 我不确定这对任何人是否有任何兴趣。 I suspect the internals for declaring and defining/allocating a struct cause this phenomenon -- maybe someone can confirm/explain. 我怀疑声明和定义/分配结构的内部导致这种现象 - 也许有人可以确认/解释。

#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;
}

UPDATE: Compilation with g++ instead of MSVC does not show a difference in output. 更新:使用g ++而不是MSVC进行编译不会显示输出的差异。 Seems hence to be compiler-specific... 因此似乎是编译器特定的......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM