memory alocated problem

I have a problem about memory allocated, I read through my code and think threre is no problem, but it did happens, it very confusing me ...., here is my code: the problem lies in a[] when the Class Grid
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include <iostream>
using namespace std;

typedef int Coordinate;
typedef int Threatvalue;
typedef double Wgt;

class GridUnit;
inline ostream& operator <<(ostream& out, GridUnit& p);//
class GridUnit
{
public:
	enum   NO{N1=8};
	GridUnit( ):index(0), x(0),y(0),value(1),a(new Wgt[N1]){ 
		for (int i=0; i<N1; ++i)
		{
			a[i] = 0.0;
		}
		cout<<"ctor1 is called!"<<endl;}
	
	~GridUnit( )	{cout<<"dctor is called!"<<endl; 
	delete[ ] a;}

	int getIndex() const {return index;}
	Coordinate getX() const{return x;}
	Coordinate getY() const{return y;}
	Threatvalue getValue() const	{return value;}
	Wgt getWgt( int i) const {return a[i];}


	void setIndex(int newi)  {index=newi; }                    //
	void setX(Coordinate newx)  {x = newx;}
	void setY(Coordinate newy)  {y = newy;}
	void setValue(Threatvalue newval) {value=newval;}
	void setWgt(int i, Wgt v) { a[i]= v;}

	void InitialSet(int i, int n){
		index=i;
		x = index%n;
		y = index/n;
		value=1; 
	
		if (!a)
		{
			cout<<"//////"<<endl;
		}
	}	
protected:
private:
	int        index;// 关系 index/dimension=y,     index%dim=x;
	Coordinate x;
	Coordinate y;
	Threatvalue  value;
	Wgt* a;

};

class Grid
{
public:
	Grid() { };
	Grid(int dim):n(dim),cnt(0),gunit(new GridUnit[dim*dim])  {   memset(gunit, 0, n*n*sizeof(GridUnit));}
	~Grid( )
	{	delete []gunit; }

	int getdim() const {return n;}
	int getcnt()  const {return cnt;}

	GridUnit& getGridUnit(int index ) 
	{
		if (index>n*n-1)
		{cout<<"gunit[index] bound error!"<<'\n';}
		return gunit[index];
	}

	void InitialGrid( ){
		int i=0;
		int lim=n*n;
		for (i=0; i<lim; ++i )
		{
			GridUnit& tmp = getGridUnit(i);
			tmp.InitialSet(i, n);
			cnt++;
		}//
	}

protected:
public:
	int  n;					  //dimension
	int  cnt;				 //count the number of gridpoints have been initialized
	GridUnit* gunit;      //array for gridpoints 
};

int main()
{
	Grid test(2);
	test.InitialGrid( ); // this shows that a[] is not exist?

// 	GridUnit& tmp = test.getGridUnit (0);
// 	tmp.getWgt (4); // get error?
	return 0;
}
The error is that you create a GridUnit array of size four in Grid test(2);, then you access the fifth element with tmp.getWgt (4);.

Additionally,
memset(gunit, 0, n*n*sizeof(GridUnit));
Why does this code exist in Grid constructor? It's wrong. GridUnit should initialise itself.

GridUnit& tmp = getGridUnit(i);
In Grid::InitialGrid, what is tmp referencing?
The error is that you create a GridUnit array of size four in Grid test(2);, then you access the fifth element with tmp.getWgt (4);.
tmp.getWgt (4); is not out of boundary, as a[] in Class GridUnit have N1=8 elements.

tmp is just a loacal variant, the func getGridUnit(i) return a reference. I want to set the a[] which belongs that by tmp.InitialSet(i, n).
Thanks to kbw, this problem is really caused by over initializatin (memset(gunit, 0, n*n*sizeof(GridUnit));.
GridUnit has a pointer to the array, a. The memset in Grid's constructor is overwritting a with null. Later on, you try to index an array starting at 0.

You should address the tmp reference too.
Also overwriting a class object using memset like that can trash the object (for example - it
can destroy the VFT pointer).
You should address the tmp reference too.

why tmp reference is not appropriate here? Can you explain it for me? I really don't know why, because after removing the superfluous initialization, the code runs well.


Also overwriting a class object using memset like that can trash the object (for example - it
can destroy the VFT pointer).


By the way, what is the VFT ponter?
If a class contains virtual functions then there is a hidden pointer which is stored along with objects of that class that points to the virtual function table. So there is more to a class/object than just the data and functions that you defined for it.
If you trash this pointer then a crash will happen when you try to call a virtual function:

Here is what I mean:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class base
{
  public:
  virtual void doSomething(void) {cout << "Hello from Base" << endl;}
};

class derived  :public base
{
  public:
  void doSomething(void) { cout << "Hello from Derived" << endl;}
};

int main() 
{
  base bb;
  derived dd;

  base *pbase;
  
  memset(&dd,0,sizeof(dd) ); //oops! overwriting derived class object
  
  pbase = &dd; //base pointer pointing to derived class

  pbase->doSomething(); //virtual function call in action - should crash

	return 0;
}
I'm wrong again! There's nothing wrong with dUnit& tmp = getGridUnit(i);
Topic archived. No new replies allowed.