Reputation: 13
this might've been already asked but probably in different way. I've searched long but I just cannot find my answer. And I've spent nearly a whole day trying to solve this little problem so I am pretty frustrated and can't think straight anymore...
Anyway, I have problem with accessing dynamic struct. Tried many different ways yet with no avail. Here is a small example: Let's say we have 5 files. A main, where the functions from function.cpp are called. Here is function.cpp:
#include "struct.h"
#include <iostream>
void fc_a()
{
int a = 0;
std::cin >> a; //let's say 30
struct1* struct_test = new struct1[a];
struct_test[20].str = "Test";
std::cout << struct_test[20].str << std::endl;
}
void fc_b()
{
struct1 *struct_test; // just experimental, thought it would load the values
int b = 20; // dynamic as well, this is just for test
std::cout << struct_test[b].str << std::endl;
}
function.h has the stuff necessary for main to call then there is our struct (struct.h for example)
#ifndef STRUCT_H_INCLUDED
#define STRUCT_H_INCLUDED
#include <string>
struct struct1
{
std::string str;
int a;
int b;
};
#endif // STRUCT_H_INCLUDED
(and with it would go struct.cpp)
#include "struct.h"
extern struct1 struct_test; //also tried with pointer
(So in this example, I am call fc_a to dynaically expand the struct to cin size (30 for example) and then putting inside 20th index of struct inside the string the "test" value. In fc_b I'm trying to access the 20th location and coutting the value "test".
The thing is, this just crashes the program (if imput is 30, on lower values it does some weird stuff), and I have no ideas for fixes anymore. I just want to access this struct from any cpp file, save the values in it, and use them for later work. The most troubles come from the fact that it's dynamic, so when I've tried to fix it in different ways, compiler mostly wouldn't accept anything without [] or would just complain about "no reference to" error etc. Any ideas?
Upvotes: 1
Views: 279
Reputation: 73376
You have defined your class/struct struct1
in struct.h
. When you then declare extern struct1 struct_test
, you tell the compiler that you have defined an object sruct_test
of type struct1
as a global variable somewhere else.
If this object is not defined somewhere as a global variable, you'd get a linker error.
If you have defined such an object as global variable, you won't have a linking error, and everything is fine. However, in your functions, whenever you write:
struct1* struct_test = new struct1[a];
you create a local object also called struct_test
but that is completely independent of the global object defined somewhere else. It even has a different type (here it is a pointer). As soon as the function returns, this local object is destroyed, and its content lost. SO here, you would leak memory.
Now the things can get worse if you would define your global variable as a pointer as well:
struct1* struct_test; // somewhere out of any function
This global variable would automatically be initialised to a nullptr
. Now in your function, you could have the impression you initialise the global variable, while in reality you are initaliing the local one. THen later in another function you could access elements of struct_test
. As the global variable is still nullptr, you would obtain undefined behaviour (example: memory corruption, segmentation fault, freeze, all kinds of weird behaviour, and even things might appear normal).
// function.cpp
#include "struct.h"
...
extern struct1* struct_test; // tell that it's defined somewhere else
void fc_a()
{
int a = 0;
std::cin >> a; //let's say 30
struct_test = new struct1[a]; // refer to the global variable without redefining it
if (a>20) {
struct_test[20].str = "Test";
std::cout << struct_test[20].str << std::endl;
}
else std::cout << "Ooops ! Just avoided a bad subscript !!" <<std::endl;
}
// other.cpp
#include <struct.h>
struct1* struct_test; // no extern: it's really defined here
THis first solution can help at the beginning when you learn. It should haowever be avoided before you take bad habits.
One possibility, would be to return the pointer from the function where you allocate it, and then pass this pointer as argument to the function that need it.
A second possibility would be a step further to use vector<struct1>
. You can then pass the vector by value or by reference, but you avoid having to care for memory allocation.
Upvotes: 1