Heap coruption problem

Hi guys.I am just giving a little part of code.I have problem with HEAP corruption
after calling a destructor after debugging.
1
2
3
4
5
6
7
8
9
10
11
12
  class LongNumbers{
int *number;
int n;//size of number
public:
LongNumbers(int a)
{n=a;
number=new int[n];
}
~LongNumbers()
{delete [] number;}


I know if I had array of pointers for example Ponters **p,and every p[i] points to something I call 2 times delete.
1
2
3
for(int i=0;i<number_of_pointers;i++)
delete [] p[i];
delete [] p;

Is this second case correct or...


Last edited on
You're not showing the relevant code, but since you said "calling a destructor", my response is: DON'T.

Simply don't manually call a destructor. The point of a destructor is to be automatically called when a statically allocated object goes out of scope, or when delete is called on an new'd (dynamically allocated) object.

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
// Example program
#include <iostream>
#include <string>

struct Foo {
    Foo(std::string name)
    {
        this->name = name;
        std::cout << "Foo(" << name << ")::ctor\n";   
    }
    ~Foo()
    {
        std::cout << "Foo(" << name << ")::dtor\n";   
    }
    
    std::string name;
};

int main()
{
    Foo foo("banana");
    Foo* p_foo = new Foo("apple");
    
    std::cout << "main about to end...\n";
}

Foo(banana)::ctor
Foo(apple)::ctor
main about to end...
Foo()::dtor

Notice that Foo(apple)'s destructor (dtor) is never called.

Edit: Fixed small mistake in example.

Edit 2: Your edit shows that you're not calling the destructor itself. This is good.
Last edited on
My first suggestion would be to make the default ctor initialise your class properly.

Can you just show us a complete example that reproduces your issue?
What type is p? What type is p[i]?
Here is my code on my language Serbian Dugackibroj-LongNumbers
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
#include <iostream>
using namespace std;
#include"Zoo.h"
#include"DugackiBroj.h"
int main()
{
	int a;
	int *p;
	try {//I would add more functions in try block later this is a beginning
		Zoo<int> z1(4);
		Zoo<DugackiBroj> z2(4);
		for (int i = 0; i < 4; i++)
		{
			cout << "Unesite ceo broj i dugacak broj" << endl;
			cin >> a;
			DugackiBroj pom(a);
			cin >> pom;
			z1.Dodaj(a);
			z2.Dodaj(pom);

		}//after this block error

	}
	catch (const char * error)
	{
		cerr << "An error has occured -" << error << endl;
	}
		
	
		return 0;
}


Zoo.h
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#pragma once
#include<iostream>
#include <fstream>
using namespace std;
template<class T>
class Zoo
{
	int tragac;
	int d;
	T *niz;
public:
	Zoo(int a);
	~Zoo();
	void Dodaj(T a);
	void Ukloni();
	T Suma(int a, int b);
	void Snimi_u_fajl(char * c);
	void Ucitaj_iz_fajla(char * c);
};

template<class T>
inline Zoo<T>::Zoo(int a)
{
	d = a;
	tragac = 0;
	niz = new T[d];
}

template<class T>
inline Zoo<T>::~Zoo()
{
	delete[] niz;
}

template<class T>
inline void Zoo<T>::Dodaj(T a)
{
	
	if (tragac == d)
	{
		T *pom;
		pom = new T[d + d];
		for (int i = 0; i<d; i++)
			pom[d+d-i-1] = niz[d-i-1];
		delete[] niz;
		niz = pom;
		d = 2 * d;
		for (int i = d - tragac; i < d; i++)
			niz[i - 1] = niz[i];
		niz[d - 1] = a;
		//Predefinisati operator =
		tragac++;
	}
	for (int i = d - tragac; i < d; i++)
		niz[i - 1] = niz[i];
	niz[d-1] = a;
	tragac++;

	

}

template<class T>
inline void Zoo<T>::Ukloni()
{
	if (tragac == 0)
		throw "Niz je prazan";
	T * pom;
	pom = new T[d - 1];
	for (int i = 0; i < d - 1; i++)
		pom[i] = niz[i];
	delete[] niz;
	niz = pom;
	--d;
	--tragac;
}

template<class T>
inline T Zoo<T>::Suma(int a, int b)
{
	T pom = T();
	for (int i = a; i < b; i++)
		pom = pom + niz[i];// predefinisati operator +
	return pom;
}

template<class T>
inline void Zoo<T>::Snimi_u_fajl(char * c)
{
	ofstream f(c);
	if (!f.good)
	{
		throw "Nije se dobro otvorio fajl";
		f.close();
	}
	for (int i = d - tragac; i < d; i++)
		f << niz[i];
	f.close();
}

template<class T>
inline void Zoo<T>::Ucitaj_iz_fajla(char * c)
{
	ifstream f(c);
	if (!f.good)
	{
		throw "Nije se dobro otvorio fajl";
		f.close();
	}
	f >> d;
	if (!f.good)
	{
		throw "Nije se dobro ucitao element";
		f.close();
	}
	int i = 0;
	while (i < d)
		f >> niz[d - i];
	f.close();
}

DugackBroj.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#pragma once
#include<istream>
using namespace std;
class DugackiBroj
{
	int popunj;
	int f;
	int * broj;
public:
	DugackiBroj() { popunj = 0; f = 0; broj = nullptr; }
	DugackiBroj(int a);
	DugackiBroj(const DugackiBroj &b);
	~DugackiBroj();
	friend istream& operator>>(istream &in, DugackiBroj & b);
	friend ostream& operator<<(ostream &out,const  DugackiBroj & b);
	DugackiBroj& operator=(const DugackiBroj &b);
	friend DugackiBroj operator+(const DugackiBroj &b1, const DugackiBroj &b2);
};

DugacakBroj.cpp
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
#include "DugackiBroj.h"

DugackiBroj::DugackiBroj(int a)
{
	f=a;
	broj = new int[a];
	popunj = 0;
}

DugackiBroj::DugackiBroj(const DugackiBroj & b)
{
	popunj = b.popunj;
	f = b.f;
	broj = new int[f];
	for (int i = 0; i < f; i++)
		broj[i] = b.broj[i];
}


DugackiBroj::~DugackiBroj()
{
	delete[] broj;
}

DugackiBroj & DugackiBroj::operator=(const DugackiBroj & b)
{
	if (this == &b)
		return *this;
	popunj = b.popunj;
	f = b.f;
	delete[] broj;
	broj = new int[f];
	for (int i = 0; i < f; i++)
		broj[i] = b.broj[i];
	return *this;
}

istream& operator>>(istream & in, DugackiBroj & b)
{
	int i = 0;
	while (in >> b.broj[i] && i < b.f)
	{
		i++;
		b.popunj++;
	}
	return in;
	
}

ostream& operator<<(ostream & out,const DugackiBroj & b)
{
	for (int i = 0; i < b.popunj; i++)
		out << b.broj[i];
	return out;
	 
}

DugackiBroj operator+(const DugackiBroj & b1, const DugackiBroj & b2)
{
	int pom;
	int prenos = 0;
	DugackiBroj b;
	DugackiBroj b3;
	if (b1.popunj > b2.popunj)
	{
		b = b1;
		pom = b2.popunj;
		b3 = b2;;
	}
	else
	{
		b = b2;
		pom = b1.popunj;
		b3 = b1;
	}
	for (int i = 0; i < pom; i++)
	{
		
		if (b.broj[b.popunj - i] + b3.broj[b3.popunj - i] + prenos > 10)
		{
			b.broj[i] += b3.broj[i] - 10 + prenos;
			prenos = 1; 
		}
		else
		{
			b.broj[i] += b3.broj[i]  + prenos;
			prenos = 0;
		}
		
		return b;

	}

}
Last edited on
And which object is experiencing heap corruption when being deleted? Know would help us narrow down where the issue is.
Object DugackiBroj pom.Line 16 previous post first code.
I can't even compile your code, you have errors on the lines where you have if (!f.good).

It should be if (!f.good())
http://www.cplusplus.com/reference/ios/ios/good/

I think one runtime issue might be here:
1
2
3
4
5
	while (in >> b.broj[i] && i < b.f)
	{
		i++;
		b.popunj++;
	}


On the line that you mention (pom object), you initialize the array to be a size of "a".
You attempt to access b.broj[i] before checking if i < bf.

In other words, you're accessing out-of-bound indices of your array.

Switch to order of your &&
1
2
3
4
5
	while (i < b.f && in >> b.broj[i])
	{
		i++;
		b.popunj++;
	}
Last edited on
Thank you very much.I never though that order of && is important and that it can make a difference in the code.
You're welcome. There might be other issues beyond that, I didn't dig too far in.

Yes, the && operator will do what's known as "short-circuiting" and prevent the second test from being executed if the first test fails.

As soon as you try to put information into an invalid index in b.broj[i], your program is invalid, so it has to be prevented from happening in the first place.
Topic archived. No new replies allowed.