Of Memory Management, Heap Corruption, and C++
These are relatively cheap mechanisms for possibly solving the problem:
- Keep an eye on my heap corruption question - I'm updating with the answers as they shake out. The first was balancing
new[]
anddelete[]
, but you're already doing that. - Give valgrind more of a go; it's an excellent tool, and I only wish it was available under Windows. I only slows your program down by about half, which is pretty good compared to the Windows equivalents.
- Think about using the Google Performance Tools as a replacement malloc/new.
- Have you cleaned out all your object files and started over? Perhaps your make file is... "suboptimal"
- You're not
assert()
ing enough in your code. How do I know that without having seen it? Like flossing, no-oneassert()
s enough in their code. Add in a validation function for your objects and call that on method start and method end. - Are you compiling -wall? If not, do so.
- Find yourself a lint tool like PC-Lint. A small app like yours might fit in the PC-lint demo page, meaning no purchase for you!
- Check you're NULLing out pointers after deleteing them. Nobody likes a dangling pointer. Same gig with declared but unallocated pointers.
- Stop using arrays. Use a vector instead.
- Don't use raw pointers. Use a smart pointer. Don't use
auto_ptr
! That thing is... surprising; its semantics are very odd. Instead, choose one of the Boost smart pointers, or something out of the Loki library.
C++ Heap Corruption but only in Unit Test Project
Thanks to a combination of users, the problem has been fixed. It was the push function that caused an error.
The push function has been changed from:
void push(T _item)
{
if (m_size + 1 == MAX_SIZE + 1)
{
throw StackOverflowException();
}
m_array[++m_top] = _item;
++m_size;
}
To:
void push(T _item)
{
if (m_size == MAX_SIZE)
{
throw StackOverflowException();
}
m_array[m_size] = _item;
++m_size;
++m_top;
}
The constructor has been changed from:
Stack() : m_array(new T[MAX_SIZE]), m_size(0), m_top(0) {};
to
Stack() : m_array(new T[MAX_SIZE]), m_size(0), m_top(-1) {};
Now size and top are not the same anymore, and m_top
actually points to the top of the stack.
What can explain heap corruption on a call to free()?
In general the possibilities include:
- Duplicate free.
- Prior duplicate free.
- (Most probable) Your code wrote beyond the limits of the allocated chunk of memory, either before the beginning or after the end.
malloc()
and friends put extra bookkeeping information in here, such as the size, and probably a sanity-check, which you will fail by overwriting. - Freeing something that hadn't been
malloc()
-ed. - Continuing to write to a chunk that had already been
free()
-d.
Heap corruption when freeing allocated memory (C)
Item* item = (Item*) malloc(sizeof(Item*));
You should change that sizeof
to sizeof(Item)
or sizeof(*item)
. Otherwise you'll allocate just enough to hold a pointer, not nearly enough for your structure.
Personally I prefer sizeof *item
- that way if I ever change its type, I only have to do it in one place.
Side notes:
- What the corruption means: since you allocated to little memory, when
you filled your struct fields to messed up the internal bookkeeping
ofmalloc
and the next operation detected it - Although a matter of personal preference, you should probably not cast the return of
malloc
Heap-corruption when freeing allocated memory
I fixed the error by changing the way I am passing variables to function,structure instead of pointers and now it works idk why but it works :).Tnx everyone for help.
Changed code:
VARIJABLE temprijec(VARIJABLE V, RIJEC *B) {
int i;
V.len = strlen((B + V.rng)->rijec);
V.temp = (char*)calloc(V.len + 1, sizeof(char));
for (i = 0; i < V.len + 1; i++) {
if (i == 0) {
V.temp[i] = (B + V.rng)->rijec[i];
}
else if (i == (V.len)) {
V.temp[i] = '\0';
}
else {
V.temp[i] = '_';
}
}
return V;
}
and
VARIJABLE tijek_igre(RIJEC *B, VARIJABLE V) {
int i;
printf("\nPogodi slovo ili rijec!");
V.ch = _getch();
for (i = 0; (B + V.rng)->rijec[i] != '\0'; i++) {
if (V.ch == (B + V.rng)->rijec[i]) {
V.temp[i] = V.ch;
}
}
for (i = 0; (B + V.rng)->rijec[i] != '\0'; i++) {
if (V.ch != (B + V.rng)->rijec[i]) {
(V.pogresno_slovo)++;
if (V.pogresno_slovo == V.len) {
(V.pogreska)++;
}
}
}
for (i = 0; V.temp[i] != '\0'; i++) {
if (V.temp[i] != '_') {
(V.tocno_slovo)++;
}
}
return V;
}
Related Topics
Template Parameter Packs Access Nth Type and Nth Element
How to Pass Derived Classes by Reference to a Function Taking Base Class as a Parameter
Problems Using Member Function as Custom Deleter with Std::Shared_Ptr
Is Writing to &Str[0] Buffer (Of a Std:String) Well-Defined Behaviour in C++11
Lnk2019: Unresolved External Symbol _Main Referenced in Function _Tmaincrtstartup
Why Don't Std::Vector's Elements Need a Default Constructor
Ways to Do Modulo Multiplication with Primitive Types
Why Does the Main Function Work with No Return Value
A Way in C++ to Hide a Specific Function
Linux C++: How to Profile Time Wasted Due to Cache Misses
Error: Class Has Not Been Declared Despite Header Inclusion, and the Code Compiling Fine Elsewhere
Why Is There No 2-Byte Float and Does an Implementation Already Exist
Vary Range of Uniform_Int_Distribution
How to Return Array from C++ Function to Python Using Ctypes