im really stuck right now...
Summary:
My C++ application crashes every time with an
Access Violation Reading Error on location 0x000000008
which must be an error by the use of multiple vectors of object pointers
where the objects are created with the new statement.
-------------
I want to train my skills by creating a simple GUI Engine with SDL2
and designed it like this:
Create Engine class/object with extern (global)
Because i want to pack all Engine related stuff like update functions
in one packet and init this via a init function:
Create GUI class/object with extern
I wanted this to also be in one "pack" and inside this class
i have multiple std::vector <#PointerToObject#> to keep
my created window objects alive on th global heap instead
of creating them temporary is this correct or is there a better
method to do so?
GUI.h
//...
class GUIWindow
{
//...
std::vector< GUIGadgetLable* > _guiGadgetLables;
std::vector< GUIGadgetButton* > _guiGadgetButtons;
//...
};
class GUI
{
//...
std::vector< GUIWindow* > _guiWindows;
//...
void createWindow(std::string title, int x, int y, int sx, int sy);
};
//...
extern GUI engineGUI;
GUI.cpp
//...
void GUI::createWindow(std::string title, int x, int y, int sx, int sy)
{
this->_guiWindows.insert(this->_guiWindows.end(), new GUIWindow(title,x,y,sx,sy));
return this->_guiWindows.at(this->_guiWindows.size()-1);
}
//...
GUI engineGUI;
I do this in many objects and my hirachy for GUI creation is like this:
GUI
1>GUIWindow
2->GUIGadgetLable
3-->GUIText
4--->ResourceTexture (createFromText)
2->GUIImage
3-->ResourceTexture (createFromFile)
2->GUIGadgetButton
3-->GUIText
Everything worked fine till i implemented my ResourceManager to capsule
the SDL texture rendering functions like load a Bitmap from a file into an SDL_Texture and create a texture from a text.
ResourceManager.h
class ResourceFont
{
public:
TTF_Font* _font = NULL;
int _fontSize = 3;
std::string _fontFile = "";
bool loadFromFile(std::string file, int fSize);
void destroy();
};
class ResourceTexture
{
public:
SDL_Texture *_texture = NULL;
SDL_Rect _size;
SDL_Rect _position;
std::string _data = ""; //File/Text
bool _visible = true;
bool _isText = false;
int _fSize = 3;
SDL_Color _textColor = {70,30,120};
bool createFromFile(std::string file, int x, int y, float sx, float sy);
bool createFromText(std::string text, int fSize, int x, int y, SDL_Color foreGround);
bool changeText(std::string text);
void resize(float sx, float sy);
void update(int x, int y);
void draw();
void destroy();
};
class ResourceManager
{
public:
std::vector< ResourceFont* > _resourceFonts;
std::vector< ResourceTexture* > _resourceTextures;
TTF_Font* addFont(std::string fontFile, int fSize);
};
extern ResourceManager engineResource;
The Texture things worked completely but after the implementation of the ResourceFont* Vector and the addFont Function (which uses TTF_Font to create a new font handle for the ResourceTexture::createFromText function) which is below the Program crashes with an access violation reading at adress 0x0...08 and this at the point where i call the
new ResourceFont()
or
return this->_resourceFonts.at(i)->_font;
in my code so i think i got my heap corrupted but i dont know why if everything with the same methods worked well until this point?
ResourceManager.cpp
TTF_Font *ResourceManager::addFont(std::string fontFile, int fSize)
{
std::cout << "GOIN "<< fSize << std::endl;
if (this->_resourceFonts.size())
{
for (unsigned int i=0; i < this->_resourceFonts.size(); i++)
{
std::cout << "Compare: " << i << " Search: " << fSize << " Found: " << this->_resourceFonts.at(i)->_fontSize << std::endl;
if (this->_resourceFonts.at(i)->_fontSize==fSize) //this->_resourceFonts.at(i)->_fontFile==fontFile&&
{
//std::cout << this->_resourceFonts.at(i) << std::endl;
if (this->_resourceFonts.at(i)->_fontSize==fSize)
{
std::cout << "Found one " << &this->_resourceFonts.at(i)->_font << std::endl;
return this->_resourceFonts.at(i)->_font; //Crashes sometimes here were it try to acces the object
}
else
{
return 0;
}
}
std::cout << "Nope" << std::endl;
}
}
std::cout << "Create One" << std::endl << std::endl;
this->_resourceFonts.insert(this->_resourceFonts.end(), new ResourceFont()); //Crashes sometimes here
this->_resourceFonts.at(this->_resourceFonts.size()- 1)->loadFromFile(fontFile,fSize);
if (this->_resourceFonts.at(this->_resourceFonts.size()-1)->_font)
{
return this->_resourceFonts.at(this->_resourceFonts.size()- 1)->_font;
}
else
{
this->_resourceFonts.at(this->_resourceFonts.size()- 1)->destroy();
return NULL;
}
}
Have anybody an idea how to solve this?
Thank you :)
Don't know if this is the real error, but the code is too large to fit in a comment.
At the very end of AddFont you have:
if (this->_resourceFonts.at(this->_resourceFonts.size()-1)->_font)
{
return this->_resourceFonts.at(this->_resourceFonts.size()- 1)->_font;
}
else
{
this->_resourceFonts.at(this->_resourceFonts.size()- 1)->destroy();
return NULL;
}
This code tests for a non-null _font, which means that in the else part the _font member is null. And it is still left in the _resourceFonts vector.
It looks like i found the Problem:
If i use the ResoruceManager::addFont() direct in every function instead of saving it in an extra TTF_Font* var the program runs normal.
Related
This is the class in question (only functions that pertain to this question) and everything it depends on (all written myself). It provides an interface to a DLL.
struct MemRegion {
const uint64_t address;
const uint64_t size;
};
enum Version {
VERSION_US,
VERSION_JP
};
const struct MemRegion SEGMENTS[2][2] = {
{{1302528, 2836576},
{14045184, 4897408}},
{{1294336, 2406112},
{13594624, 4897632}},
};
using Slot = array<vector<uint8_t>, 2>;
class Game {
private:
Version m_version;
HMODULE m_dll;
const MemRegion* m_regions;
public:
Game(Version version, cstr dll_path) {
m_version = version;
m_dll = LoadLibraryA(dll_path);
if (m_dll == NULL) {
unsigned int lastError = GetLastError();
cerr << "Last error is " << lastError << endl;
exit(-2);
}
// this is a custom macro which calls a function in the dll
call_void_fn(m_dll, "sm64_init");
m_regions = SEGMENTS[version];
}
~Game() {
FreeLibrary(m_dll);
}
void advance() {
call_void_fn(m_dll, "sm64_update");
}
Slot alloc_slot() {
Slot buffers = {
vector<uint8_t>(m_regions[0].size),
vector<uint8_t>(m_regions[1].size)
};
return buffers;
}
void save_slot(Slot& slot) {
for (int i = 0; i < 2; i++) {
const MemRegion& region = m_regions[i];
vector<uint8_t>& buffer = slot[i];
cerr << "before memmove for savestate" << endl;
memmove(buffer.data(), reinterpret_cast<void* const>(m_dll + region.address), region.size);
cerr << "after memmove for savestate" << endl;
}
}
};
When I call save_slot(), it should copy two blocks of memory to a couple of vector<uint8_t>s. This does not seem to be the case, though. The function finishes the first copy, but throws a segmentation fault at the second memcpy. Why does it only happen at the second copy, and how can I get around this sort of issue?
Edit 1: This is what GDB gives me when the program terminates:
Thread 1 received signal SIGSEGV, Segmentation fault.
0x00007ffac2164452 in msvcrt!memmove () from C:\Windows\System32\msvcrt.dll
Edit 2: I tried accessing the segments individually. It works, but for some reason, I can't access both segments in the same program.
I found out that HMODULE is equivalent to void*. Since you can't really use pointer arithmetic on void*s, you have to cast it to a uint8_t* or equivalent to properly get an offset.
Here's what that looks like in practice:
void save_state(Slot& slot) {
uint8_t* const _dll = (uint8_t*)((void*)m_dll);
for (int i = 0; i < 2; i++) {
MemRegion segment = m_regions[i];
std::vector<uint8_t>& buffer = slot[i];
memmove(&buffer[0], _dll + segment.address, segment.size);
}
}
I'm building a sparse matrix class that holds two arrays (row and column) of pointers to doubly linked lists (down and right). Sort of like this:
rows
c0123456789
o1
l2
u3
m4 A-->B-->
n5 | |
s6 | V
7 V D-->
8 C-->
9
Both arrays are initialized to have nullptr in every space until something is inserted in that place.
I have a function "readFile" that reads in objects from a text file and inserts them into this sparse matrix. For some reason, before this function returns, all of the data in it is fine, but after I return, I get random memory locations in my arrays. Here is main.cpp
#include <iostream>
#include <string>
#include <fstream>
#include "sparseMatrix.h"
using namespace std;
class basic
{
private:
int x, y;
string word;
basic *down;
basic *right;
public:
basic(int x, int y, string word)
{
this->x = x;
this->y = y;
this->word = word;
down = nullptr;
right = nullptr;
}
int getX()
{
return x;
}
int getY()
{
return y;
}
basic *getRight()
{
return right;
}
void setRight(basic *newRight)
{
right = newRight;
}
basic *getDown()
{
return down;
}
void setDown(basic *newDown)
{
down = newDown;
}
void print()
{
cout << "X: " << x << ", Y: " << y << ", word: " << word << ".\n";
}
};
sparseMatrix<basic> readFileBROKEN(string pathToFile);
sparseMatrix<basic> *readFile(string pathToFile);
int main()
{
cout << "Working:\n\n";
sparseMatrix<basic> *workingMatrix = readFile("C:/users/jmhjr/desktop/testdata.txt");
cout << "After returning, here are all the locations that are NOT nullptr:\n";
workingMatrix->printyArray();
cin.get();
cout << "Not working:\n\n";
sparseMatrix<basic> brokenMatrix = readFileBROKEN("C:/users/jmhjr/desktop/testdata.txt");
cout << "After returning, here are all the locations that are NOT nullptr:\n";
brokenMatrix.printyArray();
cin.get();
delete workingMatrix;
}
sparseMatrix<basic> readFileBROKEN(string pathToFile)
{
ifstream inputFile;
inputFile.open(pathToFile);
if (inputFile.fail())
{
cout << "Couldn't open " << pathToFile << "!\n";
exit(-1);
}
sparseMatrix<basic> matrix(100, 100);
while (!inputFile.eof())
{
int x, y;
string word;
inputFile >> x >> y >> word;
basic data(x, y, word);
matrix.insert(data);
}
cout << "Before returning, here are all the locations that are NOT nullptr:\n";
matrix.printyArray();
cout << "press ENTER to return\n";
cin.get();
return matrix;
}
sparseMatrix<basic> *readFile(string pathToFile)
{
ifstream inputFile;
inputFile.open(pathToFile);
if (inputFile.fail())
{
cout << "Couldn't open " << pathToFile << "!\n";
exit(-1);
}
sparseMatrix<basic> *matrix = new sparseMatrix<basic>(100, 100);
while (!inputFile.eof())
{
int x, y;
string word;
inputFile >> x >> y >> word;
basic data(x, y, word);
matrix->insert(data);
}
cout << "Before returning, here are all the locations that are NOT nullptr:\n";
matrix->printyArray();
cout << "press ENTER to return\n";
cin.get();
return matrix;
}
and here is sparseMatrix.h:
template <class dataType>
class sparseMatrix
{
private:
//The dimensions of the sparse matrix.
int width;
int height;
//Dynamic array of pointers to heads of linked lists.
dataType** xArray;
dataType** yArray;
public:
//Constructor. Sets everything in the two arrays to nullptr.
sparseMatrix(int height, int width)
{
this->width = width;
this->height = height;
xArray = new dataType*[width];
yArray = new dataType*[height];
for (int row = 0; row < height; row++)
{
this->yArray[row] = nullptr;
}
for (int col = 0; col < width; col++)
{
this->xArray[col] = nullptr;
}
}
//Deconstructor. First goes through the matrix and looks for every city it can find, and deletes
//all of those. Then when it's done, it deletes the two dynamic arrays.
~sparseMatrix()
{
dataType *currentdataType;
dataType *next;
for (int row = 0; row < height; row++)
{
currentdataType = yArray[row];
while (currentdataType != nullptr)
{
next = currentdataType->getRight();
delete currentdataType;
currentdataType = next;
}
}
delete [] yArray;
delete [] xArray;
}
//Creates a copy of the data we are passed, then creates links to this copy.
void insert(dataType data)
{
//Make sure the data is valid.
if (data.getX() < 0 || data.getX() >= width || data.getY() < 0 || data.getY() >= height)
{
std::cout << "That dataType doesn't fit into the sparse matrix!\n";
data.print();
std::cin.get();
}
else
{
//Copy the data we were passed.
dataType *newData = new dataType(data);
//Easy case. If nothing is in this row, set yArray[row] to the address of this data.
if (yArray[data.getY()] == nullptr)
{
yArray[data.getY()] = newData;
}
//Not so easy case. Move forward (right) until we find the right location, then set links.
else
{
dataType *current = yArray[data.getY()];
while (current->getRight() != nullptr)
{
current = current->getRight();
}
current->setRight(newData);
}
//Easy case. If nothing is in this col, set xArray[col] to the address of this data.
if (xArray[data.getX()] == nullptr)
{
xArray[data.getX()] = newData;
}
//Not so easy case. Move forward (down) until we find the right location, then set links.
else
{
dataType *current = xArray[data.getX()];
while (current->getDown() != nullptr)
{
current = current->getDown();
}
current->setDown(newData);
}
}
}
void printyArray()
{
for (int r = 0; r < height; r++)
{
if (yArray[r] != nullptr)
{
std::cout << r << ' ';
//yArray[r]->print();
}
}
}
};
readFile reads everything in from a file that looks like this:
0 0 hello
5 2 world
6 8 foo
9 5 bar
...
As expected, before returning, the only locations that are NOT nullptr are the ones that I have inserted into. (0, 2, 8 and 5). However when the function returns, EVERY SINGLE location in the array is not nullptr. I added a second function which returns a pointer to dynamically allocated sparseMatrix object, rather then returning the object itself, and this fixed it. However, I don't understand why. It seems like these two functions should behave identically the same way.
Also, the part that is most confusing to me, why does this run perfectly fine in Xcode, but not in Visual Studio?
tomse's answer is correct and gives the why and a fix, but it's an unnecessarily expensive fix for this problem. His suggestion of the copy constructor also solves numerous future problems such as the classics Why did my vector eat my data? and Dude, where's my segfault? Make the copy constructor. Don't use it unless you have to.
I think Andras Fekete got the problem right, but his post is kind of garbled. His solution is bang on, though.
Define your function like this:
bool readFile(string pathToFile, sparseMatrix<basic> & matrix)
Remove the definition of matrix inside the function in favour of the one passed in.
Return false on error so you know the matrix is bad (or use exceptions).
Create the matrix in the calling function and pass it into the revised reader function.
sparseMatrix<basic> matrix(100, 100);
if readFile("C:/users/jmhjr/desktop/testdata.txt", matrix);
That puts you right back where you were with the pointer version, but without the pointer and without having to do the extra work of copying data you didn't need to copy.
Your function:
sparseMatrix<basic> readFileBROKEN(string pathToFile)
returns a copy of the object (which is OK), but sparseMatrix does not define a copy constructor, so the default generated will be used which creates a shallow copy by just copying the adresses inside the returned object.
But the memory where the address points to is deleted when you leave your function (because the destructor of the locally created object is called).
To solve this you have to define your own copy contructor in sparseMatrix which copies all the content of the object.
sparseMatrix(const sparseMatrix& rhs) :
width(rhs.width),
height(rhs.height),
xArray(nullptr),
yArray(nullptr)
{
... and now copy all the content from rhs.xArray to this->xArray,
(same for yArray)
}
The problem is that you're allocating 'matrix' inside both of the readFile functions. Upon returning from the function, both variables are deallocated. However, returning the value (eradFile) the matrix is copied into your variable of the calling function, whereas returning the pointer (readFileBROKEN) is just returning the address where the matrix used to be stored.
To fix this, you should allocate the 'matrix' variable, and pass in a reference to the function. Then the function can return a void while stuffing the matrix properly.
i'm a Brazilian beginner in c++ coding (apologize my poor knowledge in both things). I'm trying to write an .txt output file containing the positions of pixels i click with the mouse. I'm making use of opencv library, so thats a functional part of the code:
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
using namespace cv;
//declaration of vector and counter
int i = 1;
std::vector<int>vet_x(i);
std::vector<int>vet_y(i);
//the callback function
void CallBackFunc(int event, int x, int y, int flags, void* userdata)
{
if (event == EVENT_LBUTTONDOWN)
{
vet_x.resize(i);
vet_y.resize(i);
vet_x[i] = x;
vet_y[i] = y;
i++;
cout << "Left button of the mouse is clicked - position (" << x << ", " << y << ")" << endl;
}
}
int main(int argc, char** argv)
{
Mat img = imread("lena.jpg");
//Create a window
namedWindow("Mouse Track Test", 1);
//set the callback function for mouse event
setMouseCallback("Mouse Track Test", CallBackFunc, NULL);
//show the image
imshow("Mouse Track Test", img);
// Wait until user press some key
waitKey(0);
//the writing begins after the press of the key
ofstream myfile;
myfile.open("points.txt");
for (int j = 1; j <= vet_x.size(); j++)
{
cout << vet_x[j] << "," << vet_y[j] << endl;
myfile << vet_x[j] << "," << vet_y[j] << endl;
}
myfile.close();
return 0;
}
The problem is: the file write only the last clicked position!
But if i turn the "vet_x.reserve(1024);" line, it works well, but only for the y coordinates...
So, what is my mistake?
C++ array indexing is 0-based. Thus when you resize a vector v to size 1, and assign to v[1], you're assigning to a non-existing item. This is Undefined Behavior.
To catch this kind of out-of-bounds indexing you can use the at method, which guarantees an exception. I.e., writing v.at(i) instead of v[i].
However, you should simply use the push_back member function to add items to a vector. I.e., v.push_back( x ), where x is the value that you want to add. It can also be a good idea to use a single vector of 2D points, instead of one vector for x and one vector for y.
vet_x.resize(i);
vet_y.resize(i);
vet_x[i]=x;
vet_y[i]=y;
You are assigning elements out of range, which is an undefined behavior. After resize(i) the last valid index is i-1. std::vector operator [] never insert elements in the container.
Rather just do
vet_x.push_back(x);
vet_y.push_back(y);
Your method of adding variables into vectors is wrong. I suggest this:
struct Point
{
int x, y;
Point(int sx, int sy)
:x(sx),y(sy)
{
}
};
std::vector<Point> clickedPositions;
//the callback function
void CallBackFunc(int event, int x, int y, int flags, void* userdata)
{
if ( event == EVENT_LBUTTONDOWN )
{
clickedPositions.push_back(Point(x,y));
}
}
and while writing it into the file:
for(int j=0; j<clickedPositions.size(); j++)
{
myfile << clickedPositions[j].x < <","<< clickedPositions[j].y <<endl;
}
I'm a beginner in C++ and I understand basic concepts of "pass-by-value or reference", object scope and object instantiation with and without use of the keyword "new" in simple examples. The problem is that when the problems that I'm trying to solve become more complicated, I don't know how is this theory I know from simple examples applied in problems that consists of multiple classes.
I have a PaintWidget.cpp which is responsible for painting all the Vehicles.
void PaintWidget::paintEvent(QPaintEvent *) {
if (!Vehicle::GetVehicles()->empty()) {
cout << "not null" << endl;
QPainter painter(this);
QPen pen1(Qt::red);
pen1.setWidth(2);
std::vector<Vehicle>::iterator it;
for (it = Vehicle::GetVehicles()->begin(); it != Vehicle::GetVehicles()->end(); it++) {
cout << "draaaaw" << endl;
QRect rect(it->GetXcord(), it->GetYcord(), it->GetWidth(), it->GetHeight());
cout << std::to_string(it->GetXcord()) + " " + std::to_string(it->GetYcord()) + " " + std::to_string(it->GetWidth()) + " " + std::to_string(it->GetHeight()) + " " << endl;
painter.setPen(pen1);
painter.drawRect(rect);
}
} else {
cout << "is null" << endl;
}
}
And then I have Vehicle.h
#ifndef VEHICLE_H
#define VEHICLE_H
#include <vector>
#include <map>
class Vehicle {
public:
Vehicle();
Vehicle(const Vehicle& orig);
virtual ~Vehicle();
void initVehicles();
Vehicle createVehicle();
static std::map<Road, int> &GetVeh_num() {
return veh_num;
}
static std::vector<Vehicle> *GetVehicles() {
return &vehicles;
}
private:
int xcord;
int ycord;
int height = 20;
int width = 50;
static std::vector<Vehicle> vehicles;
static std::map<Road, int> veh_num;
};
#endif /* VEHICLE_H */
Vehicle.cpp
#include "Vehicle.h"
#include <vector>
std::vector<Vehicle> Vehicle::vehicles;
std::map<Vehicle::Road, int> Vehicle::veh_num = {
{Vehicle::Top, 0},
{Vehicle::Right, 0},
{Vehicle::Bottom, 0},
{Vehicle::Left, 0}
};
Vehicle::Vehicle() {
}
Vehicle::Vehicle(const Vehicle& orig) {
}
Vehicle::~Vehicle() {
}
int Vehicle::GetXcord() const {
return xcord;
}
int Vehicle::GetYcord() const {
return ycord;
}
void Vehicle::SetXcord(int xcord) {
this->xcord = xcord;
}
void Vehicle::SetYcord(int ycord) {
this->ycord = ycord;
}
int Vehicle::GetHeight() const {
return height;
}
int Vehicle::GetWidth() const {
return width;
}
void Vehicle::initVehicles() {
for (int i = 0; i < 5; i++) {
Vehicle::vehicles.push_back(this->createVehicle());
}
}
Vehicle Vehicle::createVehicle() {
std::map<Vehicle::Road, int>::iterator it;
Vehicle v;
for (it = Vehicle::veh_num.begin(); it != Vehicle::veh_num.end(); it++) {
int &vehnum = it->second;
if (it->first == Vehicle::Road::Right) {
int xc = 520 + vehnum * this->GetWidth() + vehnum * 5;
int yc = 220;
v.SetXcord(xc);
v.SetYcord(yc);
v.SetRoad(Vehicle::Right);
}
}
return v;
}
As you can see, createVehicle returns copy of a new Vehicle which is then inserted in the static variable Vehicles. GetVehicles returns pointer to vector of inserted vehicles because I don't want to return a copy. When I run this code, nothing gets painted although there are 5 objects in the static variable (paintEvent gets called and string "draaaaw" is printed 5 times). I suspected that I have a problem with object life span, so I changed
static std::vector<Vehicle> vehicles;
to
static std::vector<Vehicle*> vehicles;
and of course instantiation of Vehicle from
Vehicle v;
to
Vehicle *v = new Vehicle();
which creates an object on the heap if I understand correctly. After all required changes in methods, my code works (all objects are painted). What I don't understand is when these objects get destroyed and why, if I'm returning a copy every single time. How come vector vehicles is not empty (I still have 5 "ghost" objects that do not contain any values I set earlier). As far as I understand creating objects with new is not recommended, so the second option are smart pointers?
Thanks :)
Edit
I purposely left out setters and getters in .h and .cpp file so that the code is as short as possible with only relevant information.
I think your main problem is you have defined an empty copy constructor:
Vehicle::Vehicle(const Vehicle& orig)
{
}
This means that when you add a Vehicle to a container, a copy is made that doesn't actually copy anything. You should delete your own constructor and let the compiler do the work for you.
You will never have a problem with object life span if you don't use pointers or references. It simply isn't possible for that to occur. The whole concept of "RAII" is that if the variable is accessible in code, it is valid.
To test this, also print out the coordinates and size of your vehicle. If that prints a valid result, you know that your issue lies in the paint function itself.
So just don't pass a pointer of the object unless you need to modify it, and even then return a reference instead of a pointer. Just make sure not to return a reference of a temporary, as that CAN lead to life span issues.
I am new to c++ programming, and this is probably a trivial problem, but I need to construct a variable sized array in a class and transfer text file data into it, see below. Here HISTORYFile >> ClusterCoord[i]; seems to take in the information fine, however when I try to get access to the info in the main program via,
cout << CoordClassExample.ClusterCoord[1] << "\n";
I get a bus error. Please help if you can!
class CoordClass{
public:
int Entries;
double * ClusterCoord;
void set_valuesCoord(ifstream &HISTORYFile,int MolAtomNum, int MolNum);
};
void CoordClass::set_valuesCoord(ifstream& HISTORYFile,int MolAtomNum, int MolNum) {
Entries=MolAtomNum*MolNum;
double *ClusterCoord = new double [Entries];
for (int i=0;i<Entries;i++) {
HISTORYFile.ignore(1000,'\n');
HISTORYFile >> ClusterCoord[i];
cout << ClusterCoord[i] << "\n";
HISTORYFile.ignore(1000,'\n');
}
}
You have a leak in the set_valuesCoord() function if you call the function twice, unless you somewhere release the resources. That's not the problem but it's a problem. Use a std::vector<>.
class CoordClass {
// ...
std::vector<double> ClusterCoord; // instead of double *ClusterCoord
// ...
};
What might be the problem is that you don't check whether the double parsed properly. If it didn't then you're accessing uninitialized memory, and that leads to undefined behaviour.
void CoordClass::set_valuesCoord(...)
{
// ...
double cluster_coord = 0;
if( HISTORYFile >> cluster_coord )
ClusterCoord.push_back(cluster_coord);
else
std::cerr << "Error parsing cluster coord.\n";
// ...
}
As an exercise showing the vector way that won't leak among other things:
Further changes would be to remove Entries and use ClusterCoord.size().
class CoordClass{
public:
int Entries;
std::vector<double> ClusterCoord;
void set_valuesCoord(ifstream &HISTORYFile,int MolAtomNum, int MolNum);
};
void CoordClass::set_valuesCoord(ifstream& HISTORYFile,int MolAtomNum, int MolNum) {
Entries=MolAtomNum*MolNum;
ClusterCoord.resize(Entries);
for (int i=0;i<Entries;i++) {
HISTORYFile.ignore(1000,'\n');
HISTORYFile >> ClusterCoord[i];
cout << ClusterCoord[i] << "\n";
HISTORYFile.ignore(1000,'\n');
}
}