I am trying to write a programme to read MRI data by using VTK and C++. But I can't get spacing of MRI raw data in main.
The "GetSpacing" only works in "ReadImageData" function. I think I made some mistake in C++ programming. But I don't know where it is.
vtkImageData* ReadImageData(string mri_imagedata_file)
{
vtkSmartPointer<vtkMetaImageReader> reader =
vtkSmartPointer<vtkMetaImageReader>::New();
reader->SetFileName(mri_imagedata_file.c_str());
reader->Update();
vtkImageData* metaimage = reader->GetOutput();
double sp[3];
metaimage->GetSpacing(sp);
cout << sp[0] << " " << sp[1] << " " << sp[2] <<endl; //<----------It works here.
return metaimage;
}
int main (int argc, char *argv[])
{
if(argc != 2)
{
cerr << "Usage: " << argv[0] << " MRI image data" <<endl;
return EXIT_FAILURE;
}
string mri_imagedata_file = argv[1];// Input "prost00.mhd"
vtkImageData* metaimage = ReadImageData(mri_imagedata_file);
double sp2[3];
metaimage->GetSpacing(sp2);
cout << sp2[0] << " " << sp2[1] << " " << sp2[2] << endl; //<-----It doesn't work here
}
Thank you for your attention.
Assuming vtkSmartPointer<vtkMetaImageReader> is a kind of smart pointer whatever, reader points to in the function is destructed when ReadImageData returns. That includes what metaimage is pointing to.
return metaimage;
// reader->~(); // Destructed here. Including what is pointed to by metaimage.
}
A good solution would be to return the smart pointer instead of metaimage. That way what is pointed to by reader will not be destructed when ReadImageData returns and will be available in main.
My assumption is that vtkMetaImageReader::GetOutput() returns pointer to some vtkMetaImageReader internal data, so when you exit ReadImageData your reader is destroyed and the pointer you return becomes invalid.
It looks like you forgot to pass the array as a parameter to GetSpacing in main, so it calls the overload that returns a double*, leaving your array untouched.
You're also printing an array called spacing although it looks like you want the spacing in sp2.
Related
I am learning C++ with pointers and trying to program a small game. I have a class PlayerManager which should create players and save them in a file.
The code compiles but when I call the method savePlayer, the pointer inside the method is valid but I cannot access the object to which the pointer is pointing.
I have searched for similar problems on internet but did not find anything similar. I may not be looking for the right keywords as I have no idea where this comes from.
I checked before the function is called and the pointer is working and I can access the object.
Inside the calling function, the pointer still has the right address but I cannot access the object. Nothing is returned.
After the calling function the pointer is still valid and the object accessible. (see //Comments in the code below)
Here are my two functions inside my PlayerManager class.
void PlayerManager::createPlayer()
{
Player *playerPtr = new Player();
std::string name;
std::cout << "Name: ";
std::cin >> name; // I entered for instance John
std::cout << std::endl;
playerPtr->setName(name);
std::cout << "PlayerPtr name before savePlayer: " << playerPtr->getName() << std::endl; // Outputs John
std::cout << "playerPtr before savePlayer: " << playerPtr << std::endl; // Ouputs the address
this->savePlayer(playerPtr);
std::cout << "PlayerPtr name after savePlayer but inside createPlayer: " << playerPtr->getName() << std::endl; // Outputs: John
delete playerPtr;
}
void PlayerManager::savePlayer(Player* playerPtr) // the called method
{
std::cout << "playerPtr inside savePlayer: " << playerPtr << std::endl; // Outputs the address
std::cout << "PlayerPtr name inside savePlayer: " << playerPtr->getName() << std::endl; // Outputs nothing
std::string const fileName = "Players/"+playerPtr->getName()+".txt";
std::cout << fileName << std::endl; // Outputs Players/.txt
std::ofstream myFile = std::ofstream(fileName.c_str());
if(myFile)
{
std::cout << "Enregistrement du nouveau joueur." << std::endl; // The code launches but no file is created.
myFile << "{"<< std::endl;
myFile << "name: " + playerPtr->getName() <<std::endl;
} else {
std::cout << "Erreur d'enregistrement du fichier." << std::endl;
}
}
I would like to be able to access the object created in createPlayer method inside the savePlayer method by passing a pointer but I just get an empty string for
playerPtr->getName()
I don't understand how the object is accessible before the call of the method and after but not inside as the address is still valid.
EDIT1
Thank you for guiding me to the obvious mistake !
Because of recuring crash of code:blocks my getName() method was deleted before I could save it and I did not think about checking it. By writing the following getName() it worked:
std::string Player::getName() const
{
return m_name;
}
Yet I do not understand why and How I got an output in createPlayer() although the method getName() was empty. Is this normal ?
EDIT 2
I'll create a new question for this strange behavior.
The code you have should work fine. My only guess is that there's something fishy about your getter function getName().
I presume you have something along these lines?
const std::string &getName() const
{
return name;
}
Online code example: https://rextester.com/INHG32142
I'm developing a DLL (in Visual Studio 2013) to read TIFF (satellite images), using GDAL library, and having an issue to get back my variable with data - currently it empty (returns NULL).
In my DLL I have my funcion defined in the "RasterFuncs.h" like this:
namespace RasterFuncs
{
// This class is exported from the RasterFuncs.dll
class MyRasterFuncs
{
public:
// Open a raster file
static RASTERFUNCS_API int Open(char* rname, GDALDataset *poDataset);
};
}
and in my DLL cpp I have the following:
namespace RasterFuncs
{
int MyRasterFuncs::Open(char* rname, GDALDataset *poDataset)
{
poDataset = (GDALDataset *) GDALOpen(rname, GA_ReadOnly);
if (poDataset != NULL)
{
cout << "RasterXSize 1:" << poDataset->GetRasterXSize() << endl;
cout << "RasterYSize 1:" << poDataset->GetRasterYSize() << endl;
cout << "RasterCount 1:" << poDataset->GetRasterCount() << endl;
}
return 0;
}
}
at this point I have the poDataset with all image data.
However, I call this DLL form another CPP using the following code:
rfileName = "C:/Image1.tif";
// Open raster satelitte image
GDALDataset *poDataset = NULL;
GDALAllRegister();
RasterFuncs::MyRasterFuncs::Open(rfileName, poDataset);
if (poDataset != NULL)
{
cout << "RasterXSize:" << poDataset->GetRasterXSize() << endl;
cout << "RasterYSize:" << poDataset->GetRasterYSize() << endl;
cout << "RasterCount:" << poDataset->GetRasterCount() << endl;
}
and when I test poDataset that come back, shows NULL.
Anybody could help in this issue?
Thanks in advance and best regards!
Remember that by default arguments to functions are passed by value, meaning the function have a copy of the value.
When you assign to the poDataset variable in the function, you're only changing your local copy. The calling function will not see this modification. You need to pass the argument by reference:
static RASTERFUNCS_API int Open(char* rname, GDALDataset*& poDataset);
Joachim is spot on, but on the flip side you could pass a pointer to the pointer rather than a reference to the pointer. I won't go into the pointers vs references battle, as both are good to know and understand.
static RASTERFUNCS_API int Open(char* rname, GDALDataset **poDataset);
and
RasterFuncs::MyRasterFuncs::Open(rfileName, &poDataset);
("**" means "pointer to a pointer" and "&" means "address of")
I want to store pointers in a deque that looks like this:
deque<ofImage *> pointerDeque;
void testApp::iTakeAPointer(ofImage * &pointer) {
cout << "iTakeAPointer " << &pointer << endl;
pointerDeque.push_back(pointer);
cout << "pointerDeque.back() " << pointerDeque.back() << endl;
}
When I run it I get (function is called on keypress):
keyPressed 0xbffff240
iTakeAPointer 0xbffff240
pointerDeque.back() 0x9f2e08
Because deque.push_back() creates a copy. My question is: how do I get the reference, in this case 0xbffff240, in the deque?
EDIT:
Thanks. Sometimes you don't see the wood for the trees.
Your diagnostics are incorrect. This is printing the address of the pointer, not the address the pointer holds (which is what you want):
cout << "iTakeAPointer " << &pointer << endl;
&pointer is of type ofImage**. Just use pointer:
cout << "iTakeAPointer " << pointer << endl;
Note, it must be the case that the ofImage instances contained in pointerDeque exist for its lifetime. If pointerDeque now owns the ofImage instances then consider using std::unique_ptr. If it does not own it, consider using std::shared_ptr (or boost::shared_ptr).
cout << "iTakeAPointer " << pointer << endl;
Print the pointer itself, and not its address!
void testApp::iTakeAPointer(ofImage * &pointer) {
change to
void testApp::iTakeAPointer(ofImage * pointer) { // remove ref
The following code is causing a Segmentation Fault on the .ReadFromFile line:
int main()
{
// Load in.bmp
BMP * original;
cout << "line " << __LINE__ << ": Got here!" << endl;
original->ReadFromFile("in.bmp"); //Error HERE!
int width = original->TellWidth();
int height = original->TellHeight();
cout << "line " << __LINE__ << ": Got here!" << endl;
I'm using the EasyBMP library, which is included above the main function. I know it has something to do with memory and pointers, but I can't figure out what to use in place of "original->"... I've tried (*original). and (&original). but I can't seem to get it. Any help?
Thanks!
Your pointer original is pointing to a random memory location. Trying to use it will cause the undefined behavior. You need to allocate memory for BMP object and store the address in this pointer. If you want your object to persist even after it goes out of the function use original = new BMP();(don't forget to delete it later though) else you can directly do BMP original; and use it.
You have declared BMP as a pointer but never initialized it.
Try using:
BMP original;
or
BMP *original = new BMP();
The first method will create original on the stack, and you won't have to release it. The second method creates it in the free-store, and you need to use delete to free it.
delete original;
According to the tutorial, your code should be:
BMP Image;
Image.ReadFromFile( argv[3] );
It is not necessary to use a pointer try this:
// Load in.bmp
BMP original;
cout << "line " << __LINE__ << ": Got here!" << endl;
original.ReadFromFile("in.bmp"); //Error HERE!
int width = original.TellWidth();
int height = original.TellHeight();
cout << "line " << __LINE__ << ": Got here!" << endl;
or if you need to use the heap do:
BMP* original = new BMP();
and when you are done don't forget to free the memory
delete original;
I define this structure:
struct s_molecule
{
std::string res_name;
std::vector<t_particle> my_particles;
std::vector<t_bond> my_bonds;
std::vector<t_angle> my_angles;
std::vector<t_dihedral> my_dihedrals;
s_molecule& operator=(const s_molecule &to_assign)
{
res_name = to_assign.res_name;
my_particles = to_assign.my_particles;
my_bonds = to_assign.my_bonds;
my_angles = to_assign.my_angles;
my_dihedrals = to_assign.my_dihedrals;
return *this;
}
};
and these structures:
typedef struct s_particle
{
t_coordinates position;
double charge;
double mass;
std::string name;
std::vector<t_lj_param>::iterator my_particle_kind_iter;
s_particle& operator=(const s_particle &to_assign)
{
position = to_assign.position;
charge = to_assign.charge;
mass = to_assign.mass;
name = to_assign.name;
my_particle_kind_iter = to_assign.my_particle_kind_iter;
return *this;
}
} t_particle;
struct s_bond
{
t_particle * particle_1;
t_particle * particle_2;
std::vector<t_bond_param>::iterator my_bond_kind_iter;
s_bond& operator=(const s_bond &to_assign)
{
particle_1 = to_assign.particle_1;
particle_2 = to_assign.particle_2;
my_bond_kind_iter = to_assign.my_bond_kind_iter;
return *this;
}
};
and then in my code I return a pointer to an s_molecule (typedef'd to t_molecule, but still).
Using this pointer I can get this code to work:
for (unsigned int i = 0;
i < current_molecule->my_particles.size();
i++)
{
std::cout << "Particle "
<< current_molecule->my_particles[i].name << std::endl
<< "Charge: "
<< current_molecule->my_particles[i].charge << std::endl
<< "Mass: "
<< current_molecule->my_particles[i].mass << std::endl
<< "Particle Kind Name: "
<< (*current_molecule->my_particles[i].my_particle_kind_iter).atom_kind_name
<< std::endl
<< "x: " << current_molecule->my_particles[i].position.x
<< " y: " << current_molecule->my_particles[i].position.y
#ifdef USE_3D_GEOM
<< "z: " << current_molecule->my_particles[i].position.z
#endif
<< std::endl;
}
If I replace it with:
for (std::vector<t_particle>::iterator it = current_molecule->my_particles.begin();
it !=current_molecule->my_particles.end();
it++)
{
std::cout << "Particle "
<< (*it).name << std::endl
<< "Charge: "
<< (*it).charge << std::endl
<< "Mass: "
<< (*it).mass << std::endl
<< "Particle Kind Name: "
<< (*(*it).my_particle_kind_iter).atom_kind_name
<< std::endl
<< "x: " << (*it).position.x
<< " y: " << (*it).position.y
#ifdef USE_3D_GEOM
<< "z: " << (*it).position.z
#endif
<< std::endl;
}
I now get nasty segfaults...
Not to put too much here, but I'm also getting segfaults when I tried to do this:
std::cout << "Bond ATOMS : "
<< (*current_molecule).my_bonds[0].particle_1->name
<< std::endl
Again, current_molecule is a pointer to a s_molecule structure, which contains arrays of structures, which in turn either directly have vars or are pointers. I can't get these multiple layers of indirection to work. Suggestions on fixing these segfaults.
FYI I'm compiling on Linux Centos 5.4 with g++ and using a custom makefile system.
#sbi Thanks for the good advice! I believe you are right -- the assignment overloaded operator is unnecessary and should be scrapped.
I've followed the approach of commenting out stuff and am very confused. Basically in the function that passes the pointer to my particular molecule to the main function to print, I can see all the data in that molecule (bonds, particles, name, etc) perfectly, printing with cout's.
Once I pass it to the main as a ptr, if I use that ptr with an iterator I get a segfault. In other words. Also for some reason the bond data (which I can freely print in my funct that returns to the pointer) also segfaults if I try to print it, even if I use the [] to index the vector of bonds (which works for the particle vector).
That's the best info I can give for now.
A wild guess: Are you using shared libraries. I remember having difficulties passing STL-containers back and forth across shared library boundaries.
Jason (OP) was asked in a comment by David RodrÃguez:
Are you returning a pointer to a local variable?
Jason answered:
No its a ptr to a class variable. The class is very much in existence (it contains the function that returns the molecule).
Unless you're talking of a true class variable (qualified as static), the fact that the class exists doesn't have much to do with it. Instances of a class exist, and they might have ceased to exist even if you just called a function on them.
As such, the question is:
Does the instance of the class that returned the pointer current_molecule still exist?
Or is current_molecule qualified as static, i.e. being a true class variable?
If the answer to both questions is "no", you're in Undefined County.
At this point, it becomes very important that you post source code that can be used by us here to actually reproduce the problem; it might well be located in source you aren't showing us.
Again, this issue was answered here:
Weird Pointer issue in C++
by DeadMG. Sorry for the double post.