Heap coruption problem

Feb 21, 2019 at 8:45pm
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 Feb 21, 2019 at 8:53pm
Feb 21, 2019 at 8:49pm
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 Feb 21, 2019 at 8:56pm
Feb 21, 2019 at 8:50pm
My first suggestion would be to make the default ctor initialise your class properly.

Feb 21, 2019 at 8:57pm
Can you just show us a complete example that reproduces your issue?
What type is p? What type is p[i]?
Feb 21, 2019 at 8:59pm
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 Feb 21, 2019 at 9:01pm
Feb 21, 2019 at 9:09pm
And which object is experiencing heap corruption when being deleted? Know would help us narrow down where the issue is.
Feb 21, 2019 at 9:12pm
Object DugackiBroj pom.Line 16 previous post first code.
Feb 21, 2019 at 9:27pm
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 Feb 21, 2019 at 9:28pm
Feb 21, 2019 at 9:32pm
Thank you very much.I never though that order of && is important and that it can make a difference in the code.
Feb 21, 2019 at 9:37pm
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.