I have this code:
class pointLineVCN
{
public:
int v, vc, vn;
pointLineVCN(){};
pointLineVCN(int v, int vc, int vn)
{
this->v = v;
this ->vc = vc;
this->vn = vn;
}
};
pointLineVCN* newPoint;
void Triangulation3D(pointLineVCN* point, short numOfPoints)
{
newPoint = new pointLineVCN[(numOfPoints - 2) * 3];
//Code which changes newPoint
point = newPoint;
cout<<point<<endl;
}
And on the main:
pointLineVCN *vertices = new pointLineVCN[meshes[meshNum].face[*positionSaverFN].numOfPoints];
for (int i = 0; i < meshes[meshNum].face[*positionSaverFN].numOfPoints; i++)
{
sscanf(bufferStr.c_str(), "%i/%i/%i", &faceVec, &faceTex, &faceNor);
vertices[i].v = faceVec - 1;
vertices[i].vc = faceTex - 1;
vertices[i].vn = faceNor - 1;
}
Triangulation3D(vertices, meshes[meshNum].face[*positionSaverFN].numOfPoints);
cout<<vertices<<endl;
The problem is point address changes after Triangulation3D ends. On the cout calls the output is two different addresses.
I have seen another question about this problem and the solution is using pointLineVCN** point but it did not helped.
It's changing because you're changing it:
point = newPoint;
if you don't want to change it, then don't do it.
Related
I am working on the project which using pointer (new ext...) and I don't know how to fix it, I couldn't use the delete syntax because it will break the code literally.
list<Virus*> DoClone()
{
list<Virus*> l;
Dengue *d1 = new Dengue(1), *d2 = new Dengue(1);
for (int i = 0; i < 4; i++)
d1->m_protein[i] = m_protein[i];
d1->m_dna = m_dna;
d1->m_resistance = m_resistance;
for (int i = 0; i < 4; i++)
d2->m_protein[i] = m_protein[i];
d2->m_dna = m_dna;
d2->m_resistance = m_resistance;
l.emplace_back(d1);
l.emplace_back(d2);
//delete d1;
//delete d2;
return l;
}
void DoDie()
{
this->m_dna = NULL;
memset(this->m_protein, 0, 4);
this->m_resistance = 0;
delete this->m_dna;
}
Smart pointers to the rescue:
list<std::unique_ptr<Virus>> DoClone()
{
list<std::unique_ptr<Virus>> l;
auto d1 = std::make_unique<Dengue>(1);
auto d2 = std::make_unique<Dengue>(1);
for (int i = 0; i < 4; i++)
d1->m_protein[i] = m_protein[i];
d1->m_dna = m_dna;
d1->m_resistance = m_resistance;
for (int i = 0; i < 4; i++)
d2->m_protein[i] = m_protein[i];
d2->m_dna = m_dna;
d2->m_resistance = m_resistance;
l.emplace_back(std::move(d1));
l.emplace_back(std::move(d2));
return l;
}
void DoDie()
{
m_dna.reset();
memset(this->m_protein, 0, 4);
this->m_resistance = 0;
}
It would be best if you learn to use smart pointers ASAP. Here is good lecture on topic.
Also see:
C++ Core Guidelines
R.20: Use unique_ptr or shared_ptr to represent ownership
Reason
They can prevent resource leaks.
Example
Consider:
void f()
{
X x;
X* p1 { new X }; // see also ???
unique_ptr<X> p2 { new X }; // unique ownership; see also ???
shared_ptr<X> p3 { new X }; // shared ownership; see also ???
auto p4 = make_unique<X>(); // unique_ownership, preferable to the explicit use "new"
auto p5 = make_shared<X>(); // shared ownership, preferable to the explicit use "new"
}
This will leak the object used to initialize p1 (only).
Enforcement
(Simple) Warn if the return value of new or a function call with return value of pointer type is assigned to a raw pointer.
Extra:
small refactor:
std::unique_ptr<Dengue> createDengue(int x)
{
auto d = std::make_unique<Dengue>(x);
d->m_protein = m_protein; // someone claims this is an std::array so loop is not needed
d->m_dna = m_dna;
d->m_resistance = m_resistance;
return d;
}
list<std::unique_ptr<Virus>> DoClone()
{
list<std::unique_ptr<Virus>> l;
l.emplace_back(createDengue(1));
l.emplace_back(createDengue(1));
return l;
}
void DoDie()
{
m_dna.reset();
this->m_protein = {}; // someone claims this is an std::array so this is fine
this->m_resistance = 0;
}
list<Virus*> DoClone()
{
//Why are you using a list of pointers?
//Are you handing these out?
list<Virus*> l; // Replace list<Virus> l or use smart pointers
Dengue *d1 = new Dengue(1), *d2 = new Dengue(1);
for (int i = 0; i < 4; i++){
d1->m_protein[i] = m_protein[i];
}
//if the move semantics of any of them are wrong your code will crash,
//but you don't show us what these are.
d1->m_dna = m_dna;
d1->m_resistance = m_resistance;
for (int i = 0; i < 4; i++)
d2->m_protein[i] = m_protein[i];
d2->m_dna = m_dna;
d2->m_resistance = m_resistance;
l.emplace_back(d1);
l.emplace_back(d2);
//You definitely shouldn't be deleting these you jsut gave them to a container to hold!
//delete d1;
//delete d2;
return l;
}
void DoDie(ist<Virus*>& myList)
{
//You set this to nullptr, but try to delete it in 4 lines time. This looks like a leak
//Also the fact it was a pointer means you definitely copied it wrong above
//use std::shared_ptr or std::weak_ptr if you want to share things.
this->m_dna = NULL;
memset(this->m_protein, 0, 4);
this->m_resistance = 0;
delete this->m_dna;
//Lastly you need to free the memory in your container
for(auto* item : myList){
delete item;
}
myList.clear();
}
I have this class for save receipt :
class Recept {
int Ingr_size;
char *Name;
char *Type;
char *Recipe;
struct Ingridient {
char *aName;
float Mas;
} *List_ingr;
when i trying to save ingredient name or mass by using this function:
void Recept::setIngr(const char * p, float mass) {
struct Ingridient * temp = new struct Ingridient[Ingr_size + 1];
if (Ingr_size) {
for (int i = 0; i < Ingr_size; i++)
temp[i] = List_ingr[i];
delete List_ingr;
List_ingr = temp;
}
List_ingr[Ingr_size].aName = new char[strlen(p) + 1];
strcpy(List_ingr[Ingr_size].aName, p);
List_ingr[Ingr_size].Mas = mass;
}
I get an error that "Unable to reach aName memory" & "Unable to reach Mas memory".
I can't find the problem where or why.
Thank you.
I get an error that "Unable to reach aName memory" & "Unable to reach Mas memory".
this is a runtime exception, you have not initiaized your class variables, you need at least a constructor which will do basic default initailizations:
Recept() : Ingr_size(0), List_ingr(nullptr){}
also, in case List_ingr is nullptr you should not try iterating it inside setIngr.
[edit]
If you have constructor as above in your class (which is not in the question), then you have other errors, see comments below:
void Recept::setIngr(const char * p, float mass) {
struct Ingridient * temp = new struct Ingridient[Ingr_size + 1];
if (Ingr_size) {
for (int i = 0; i < Ingr_size; i++)
temp[i] = List_ingr[i];
delete List_ingr;
List_ingr = temp;
}
else {
// !!! in case of Ingr_size you still need to set List_ingr,
List_ingr = temp;
}
List_ingr[Ingr_size].aName = new char[strlen(p) + 1];
strcpy(List_ingr[Ingr_size].aName, p);
List_ingr[Ingr_size].Mas = mass;
// !!! You need to increment size
Ingr_size++;
}
In the image below (Character.cpp), may I know how to create only one Initialize method that can be called to stored many sprites? Do I need to change the Texture1,Sprite,PosX,PosY, etc to array?
The initialize method will be called in my MAIN.cpp. Sorry if the explaination is not good enough. That is just my idea of doing it but will there be a better ones instead of having so many arrays?
void Character::Initialize1(string image1, float PosX1, float PosY1, float CenterX1, float CenterY1)
{
D3DXCreateTextureFromFile(Pull->GETd3ddev(), image.c_str(), &Texture1);
D3DXCreateSprite(Pull->GETd3ddev(), &sprite1);
RECT SpriteRect1;
SpriteRect1.top = 0;
SpriteRect1.bottom = 127;
SpriteRect1.left = 0;
SpriteRect1.right = 128;
SpritePos1 = D3DXVECTOR2(PosX1, PosY1);
SpriteCenter1 = D3DXVECTOR2(CenterX1, CenterY1);
}
void Character::Initialize2(string image2, float PosX2, float PosY2, float CenterX2, float CenterY2)
{
D3DXCreateTextureFromFile(Pull->GETd3ddev(), image.c_str(), &Texture2);
D3DXCreateSprite(Pull->GETd3ddev(), &sprite2);
RECT SpriteRect2;
SpriteRect2.top = 0;
SpriteRect2.bottom = 14;
SpriteRect2.left = 0;
SpriteRect2.right = 14;
SpritePos2 = D3DXVECTOR2(PosX2, PosY2);
SpriteCenter2 = D3DXVECTOR2(CenterX2, CenterY2);
}
Create the necessary initialization method in your sprite class. Then in main() create your sprites and call the appropriate initialization methods. If using lots of Sprites, it will be probably handy to put the created sprites inside a vector in order to have less code for cleanup and probably other things.
A quick example for a Sprite class called SpriteConfig, which only contains position parameters.
#include <iostream>
#include <vector>
using namespace std;
class SpriteConfig {
public:
SpriteConfig() {
top = 0;
bottom = 0;
left = 0;
right = 0;
}
void setPos(float aTop, float aBottom, float aLeft, float aRight) {
mTop = aTop;
mBottom = aBottom;
mLeft = aLeft;
mRight = aRight;
}
private:
// position parameters
float mTop;
float mBottom;
float mLeft;
float mRight;
};
int main()
{
vector<SpriteConfig*> spriteConfigs;
SpriteConfig *sprCfg;
sprCfg = new SpriteConfig();
sprCfg->setPos(1,1,1,1);
spriteConfigs.push_back(sprCfg);
sprCfg = new SpriteConfig();
sprCfg->setPos(2,2,2,2);
spriteConfigs.push_back(sprCfg);
// We now have a number of Sprites
// Add code here to do something with it.
// ...
for(vector<SpriteConfig*>::iterator it = spriteConfigs.begin();
it != spriteConfigs.end();
++it) {
// cleanup
delete (*it);
(*it) = null;
}
return 0;
}
I am currently writing an application in c++ using the openCV-lib (version 2.1).
The task was to implement a small database as a students project, using some of the features of this library. My very own implementations of the median-filter and the boxcar-filter use the cv::Mat::at method to access single pixels in a given image with both reading and writing operations.
The curious thing about this is: It works just perfect on smaller images.
but only larger images it allways generates a SIGSEGV, allways on the same coordinates.
Is this a know bug or am i really doing something wrong?
here are the most significants functions i wrote:
class point {
public:
int x,y;
};
class ImageEntry {
friend class ImageDB;
private:
string _key;
string _filename;
Mat *_data;
ImageEntry* _next;
void show(void);
public:
void operator<<(ImageFilter* x);
~ImageEntry();
ImageEntry(string filename, string key);
Vec3b GetPoint(int x, int y);
point GetSize(void);
void SetPoint(int x, int y, Vec3b color);
};
point ImageEntry::GetSize(void) {
point iRet;
iRet.x = _data->cols;
iRet.y = _data->rows;
return iRet;
}
Vec3b ImageEntry::GetPoint(int x, int y) {
Vec3b iRet;
iRet = _data->at<Vec3b>(x,y);
return iRet;
}
void ImageEntry::SetPoint(int x, int y, Vec3b color) {
_data->at<Vec3b>(x,y) = color;
}
void MedianFilter::filterImage(ImageEntry* img) {
Vec3b Points[9];
Vec3b NewColor;
unsigned char ActChan[9];
point range = img->GetSize();
for (int act_x = 1; act_x < (range.x - 1); act_x++) {
for (int act_y = 1; act_y < range.y - 1; act_y++) {
Points[0] = img->GetPoint(act_x-1,act_y-1);
Points[1] = img->GetPoint(act_x,act_y-1);
Points[2] = img->GetPoint(act_x+1,act_y-1);
Points[3] = img->GetPoint(act_x-1,act_y);
Points[4] = img->GetPoint(act_x,act_y);
Points[5] = img->GetPoint(act_x+1,act_y);
Points[6] = img->GetPoint(act_x-1,act_y+1);
Points[7] = img->GetPoint(act_x,act_y+1);
Points[8] = img->GetPoint(act_x+1,act_y+1);
for (int act_color = 0; act_color < 3; act_color++) {
for (int i = 0; i < 9; i++) ActChan[i] = Points[i][act_color];
SelSort9(ActChan);
NewColor[act_color] = ActChan[4];
}
img->SetPoint(act_x,act_y,NewColor);
}
}
}
I would really appreciate any suggestion.
Thank you for your time!
If you take a look at the function at(), which you use in the SetPoint() method, in the documentation of OpenCv, it says:
template<typename _Tp> _Tp& Mat::at(int i, int j)
Return reference to the specified matrix element.
Parameters:
i – The 0-based row index
j – The 0-based column index
Furthermore, if you look at your GetSize() method, you set iRet.y = _data->rows and then in the method filterImage() use a for loop to loop from act_y = 1 to iRet.y. The second loop, loops through the rows. At the end of this method you call SetPoint(act_x, act_y), which on its turn calls at(act_x, act_y) basically.
Recall that act_y was an index of a row, but is now being used as index of a column. I hope this suggestion is all you need to solve your problem.
Hey basically Im trying to store a "solution" and create a vector of these. The problem I'm having is with initialization. Heres my class for reference
class Solution
{
private:
// boost::thread m_Thread;
int itt_found;
int dim;
pfn_fitness f;
double value;
std::vector<double> x;
public:
Solution(size_t size, int funcNo) : itt_found(0), x(size, 0.0), value(0.0), dim(30), f(Eval_Functions[funcNo])
{
for (int i = 1; i < (int) size; i++) {
x[i] = ((double)rand()/((double)RAND_MAX))*maxs[funcNo];
}
}
Solution() : itt_found(0), x(31, 0.0), value(0.0), dim(30), f(Eval_Functions[1])
{
for (int i = 1; i < 31; i++) {
x[i] = ((double)rand()/((double)RAND_MAX))*maxs[1];
}
}
Solution operator= (Solution S)
{
x = S.GetX();
itt_found = S.GetIttFound();
dim = S.GetDim();
f = S.GetFunc();
value = S.GetValue();
return *this;
}
void start()
{
value = f (dim, x);
}
/* plus additional getter/setter methods*/
}
Solution S(30, 1) or Solution(2, 5) work and initalizes everything, but I need X of these solution objects. std::vector<Solution> Parents(X) will create X solutions with the default constructor and i want to construct using the (int, int) constructor. Is there any easy(one liner?) way to do this? Or would i have to do something like:
size_t numparents = 10;
vector<Solution> Parents;
Parents.reserve(numparents);
for (int i = 0; i<(int)numparents; i++) {
Solution S(31, 0);
Parents.push_back(S);
}
the example I gave as a comment uses copy constructor to create new objects.
You can do the following:
// override copy constructor
Solution(const Solution &solution) {
... copy from another solution
}
however be careful, as you no longer going to have exact object copy/construct if you introduce random generation in your copy constructor, i.e. Solution y = x; y != x
your best solution is something like you already have in my opinion
I have used the Boost assignment library for tasks like this. You may find it useful....