problem with delete[] in class

Hi guys. In the code below, I am making a class 'agent' and then making an array of agents in function 'main'. This throws the error given below. In the function 'main', if I remove "delete [] my_agents", then code runs fine. So my guess is that the issue is related to "delete [] ..." in the class. It will be much appreciated if you could point out the source of error. Please note that I have implemented the rule of three in the class and have given the relevant parts of the code.

Thanks in advance.
Ajay

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
//agent.h

#ifndef AGENT_H
#define AGENT_H

#include "grid.h"

//class agent
class agent
{
	public:
	int status; 
	int n_assets;
	int n_strategies; 
	int n_memory; 
	
	double * assets;  	
	double * scores;  
	int * max_stra; 
	int * decision; 
	
	//Constructor
	agent ():status(0), n_assets(0), n_strategies(0), n_memory(0), assets(NULL), scores(NULL), max_stra(NULL), decision(NULL){};
	agent (int st, int n_ass, int n_stra, int n_mem);
	agent(const agent&);
	//Destructor
	~agent();
	//Copy assignment operator overload
	agent & operator = (const agent&);  //Rule of three
	
};
#endif 


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
//agent.cpp
//File implements the class "agent".

#include "agent.h"

using namespace std;

//Constructor
agent::agent (int st, int n_ass, int n_stra, int n_mem)
{
	status = st;
	n_assets = n_ass;
	n_strategies = n_stra;
	n_memory = n_mem;
	
	int n_signals = pow(2,n_memory);
	
	assets = new double [n_assets];
	scores = new double [n_strategies];
	decision = new int [n_assets];
	max_stra = new int [n_assets];
}

//Constructor
agent::agent(const agent& new_agent)
{
	status = new_agent.status;
	n_assets = new_agent.n_assets;
	n_strategies = new_agent.n_strategies;
	n_memory = new_agent.n_memory;

	assets = new double [n_assets];
	scores = new double [n_strategies];
	decision = new int [n_assets];
	max_stra = new int [n_assets];	
	
	for(int i=0; i<n_assets; i++)
	{
		assets[i] = new_agent.assets[i];
		decision[i] = new_agent.decision[i];
		max_stra[i] = new_agent.max_stra[i];
	}
	
	for(int i=0; i<n_strategies; i++)
	{
		scores[i] = new_agent.scores[i];
	}
}

//Destructor
agent::~agent()
{
	delete [] assets;
	delete [] scores;
	delete [] decision;
	delete [] max_stra;	
	}
	
//Overloading copy assignment operator
agent & agent::operator =(const agent& new_agent)
{
	if(this != & new_agent)
	{
		delete [] assets;
		delete [] scores;
		delete [] decision;
		delete [] max_stra;		
		
		status = new_agent.status;
		n_assets = new_agent.n_assets;
		n_strategies = new_agent.n_strategies;
		n_memory = new_agent.n_memory;

		assets = new double [n_assets];
		scores = new double [n_strategies];
		decision = new int [n_assets];
		max_stra = new int [n_assets];

		for(int i=0; i<n_assets; i++)
		{
			assets[i] = new_agent.assets[i];
			decision[i] = new_agent.decision[i];
			max_stra[i] = new_agent.max_stra[i];			
		}

		for(int i=0; i<n_strategies; i++)
		{
			scores[i] = new_agent.scores[i];
		}
	}
	return *this;	
}


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
//main.cpp

#include "model.h"
#include "agent.h"

using namespace std;

int main()
{
	//Independent parameters
	int n_agents;     
	int n_stocks;     
	int n_memory;     
	int n_stratagies; 
	
	//This function reads parameter from a file - it works fine.
	read_par( n_agents, n_stocks, n_memory, n_stratagies,);
	

	//Objects
	agent * my_agents;
	my_agents = new agent [n_agents];
	
        //Stuff here - works fine.
        
	delete [] my_agents;
	return 0;
}



*** glibc detected *** ./market: free(): invalid next size (fast): 0x099fd428 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x75ee2)[0x21dee2]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZdlPv+0x1f)[0xcb451f]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZdaPv+0x1b)[0xcb457b]
./market[0x804ad0c]
./market[0x804999f]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x1c14d3]
./market[0x804972d]
======= Memory map: ========
......
......
......
Aborted (core dumped)

I don't see any problem with the code you posted.

Usually when delete[] craps out it's because the allocated memory has been corrupted. This happens when you step out of bounds of the allocated array. So the problem is likely in how you're accessing my_agents. Double check to make sure you're never going out of bounds when you access it.


Although... is there a reason you can't use vectors? This would be a lot simpler if you could.
Thank you Disch. I have check again but so far, the problem remains the same.

To save the final data, I am using a package which takes array as input. So I don't want to use vectors here.
I'm not seeing any issues either. Do you mind posting the code that deals with my_agents? The issue is likely there, or with one of the several dynamic arrays you have in the agent class. There's a lot of allocating and deleting going on, I'd make sure you're not deleting already deleted memory when the destructor gets called.
I have check again but so far, the problem remains the same.


Can you post more code? There's obviously a bug somewhere, and I don't think it's in the code you posted. Without seeing more code I won't be able to diagnose further.

To save the final data, I am using a package which takes array as input. So I don't want to use vectors here.


Vectors are stored as linear arrays (memory is guaranteed to be contiguous with vectors). So you can pass a vector's data to a function which is expecting an array.

1
2
3
4
5
6
7
8
9
10
11
12
13
void func_that_takes_array(int* ar, int size)
{
  //...
}

int main()
{
  vector<int> foo;
  foo.resize(15);

  func_that_takes_array( foo.data(), foo.size() );  // OK (C++11)

  func_that_takes_array( &foo[0], foo.size() );  // OK (if your compiler doesn't support C++11) 



So unless the routines you're communicating with are actually resizing the arrays (doubtful), you can still use a vector. Which would not only greatly simplify this, but also... in debug builds, vectors often do bounds checking, so the bug would be immediately exposed.
Thank you Disch and ResidentBiscuit! You were right and I managed to find the error in other part of the code. Affirmation on the posted code was necessary to be sceptical about the other piece, particularly when that seemed to work fine! Also, thanks for tips on using vectors.
Topic archived. No new replies allowed.