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. 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:
#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;/开发者_JAVA技巧/length (n+1)
int n;
};
MyStruct ConstructModel();
#endif
Console output
On my machine (WinXP 32bit, MSVC2008), this gives:
myModel goes first:
myModel.Y[0]=1.12947e-307
myModel.Y[1]=1.80243e-307
myModel.n=2
now myOtherModel:
myOtherModel.Y[0]=0.1
myOtherModel.Y[1]=0.1
Your struct contains a naked pointer to doubles. In defs.cpp, you're initializing that to a local variable. Outside the scope of ConstructModel()
, that memory is no longer valid.
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). But rather than using arrays, why don't you use e.g. std::list<double>
or std::vector<double>
?
The problem is that the array Y
contained in ConstructModel
is only valid for as long as ConstructModel
is being executed. 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
:
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:
}
When the function ConstructModel finishes the array gets out of scope. 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. Seems hence to be compiler-specific...
精彩评论