Memory allocator causing mysterious pause - c++

I should probably be sleeping. Instead, I'm coding. Specifically, I've written The World's Worse Memory Allocator(TM). It's got an array of bytes (chars) to use for memory for stuff; it's got a list of used memory blocks; it's got an index to allocate memory from. It even allocates memory. Deallocates, not so much.
That shouldn't be a problem, though, as to the best of my knowledge, nothing is new'd outside of the array and list classes and the destructor for those is called the proper number of times.
Edit: The problem is, the program enters what appears to be an infinite loop somewhere in the c++ back-end code itself, shortly after the MemoryManager's destructor is called. In fact, if the MemoryManager is put inside the Try-Catch block, the program never makes it outside the Try-Catch block. I need to know why and how to fix it, please, thanks.
This is the main loop which is doing terribly important allocations:
int _tmain(int argc, _TCHAR* argv[])
{
MemoryManager memoryManager = MemoryManager(1024);
try
{
int * n;
for (int t = 0; t < 32; ++t)
{
n = (int*)memoryManager.Allocate(4);
}
} catch (char* str) { std::cout << str; }
return 0;
}
And the MemoryManager, in all it's newbie glory:
// A memory manager
#pragma once
#include "stdafx.h"
#include "Array.h"
#include "SmartPointer.h"
class MemBlock
{
public:
unsigned int Start;
unsigned int End;
MemBlock() { Start = 0; End = 0; }
MemBlock(unsigned int start, unsigned int end)
{
Start = start; End = end;
}
~MemBlock() { }
};
class MemoryManager
{
private:
Array<char> memory;
List<MemBlock> memBlocks;
int index;
public:
MemoryManager(unsigned int size)
{
memory = Array<char>(size);
memBlocks = List<MemBlock>(size / 24);
index = 0;
}
~MemoryManager() { }
void* Allocate(unsigned int size)
{
memBlocks.Add(&MemBlock(index, index + size));
void* r = (void*)(memory.insecureAccess + index);
index += size;
return r;
}
};
Thanks.

You don't seem to have asked a question here, but I'm going to point out a horrible flaw in your approach anyway :)
If you are planning to write a Deallocate(void*) method then you are going to struggle.
You can match the void* pointer against your memBlocks list to determine which MemBlock it is, but you will only be able to reduce index if that MemBlock happens to be the last one returned by Allocate otherwise it is just a free hole in your array.
For a basic solution to this you would need a list of the free blocks and you would take allocated blocks from that list, and add them back to the list when they were deallocated.
This approach is called a free list: http://en.wikipedia.org/wiki/Free_list

Solved - Error in ignorance; it was an indirect error. I was using "delete theArray;" in the Array destructor (Array also being the base class of List) when I should have been using "delete [] theArray". The pause is now gone and the problem seems solved. Thanks for your time.

Related

Program Gives An Error Every Time After Working Once

I'm attempting to implement my own array using pointers in C++. I'm using Visual Studio. I'm relatively new to C++, so if there is something obvious that I'm missing bear with me. But when I run it the first time, it works as intended. However, the next time I run it, I get one of two errors. One of the errors is
Unable To Start Program, Access Denied.
"the path of the file"
Access Is Denied
The other one that comes up rarely is
main.cpp has triggered a breakpoint
I think it has something to do with a wrong use of pointers, however that doesn't explain why it works the first time. Here is the code:
In main.cpp:
#include <iostream>
#include <vector>
#include "linked_list.hpp"
#include "trie.hpp"
#include "stack.hpp"
#include "queue.hpp"
#include "array.hpp"
int main() {
data_structures::array arr(5);
arr.set(4, 1);
int fourth_index = arr.get(4);
std::cout << fourth_index;
}
In array.hpp:
#pragma once
namespace data_structures {
class array {
private:
int* start;
public:
array(int size) {
start = new int(0);
for (int i = 1; i < size; i++) {
*(start + i) = 0;
}
}
public:
void set(int index, int val) {
if (index == 0) {
start = new int(val);
} else {
*(start + index) = val;
}
}
int get(int index) {
return *(start + index);
}
};
}
The first time, I get the correct output:
1
Then the next time I get the error I stated above.
Try changing this line:
start = new int(0);
to:
start = new int[size];
new int(0) is initializing "start" as a pointer to just one int with a value of 0. Instead, you need to allocate the memory necessary to hold your array. I suspect you're running into issues because you're writing into memory that you haven't allocated yet.
As a side note, make sure to add a destructor and free your memory.
Well you must be right! It is a memory issue and the error message "main.cpp has triggered a breakpoint" on windows indicates corruption of the heap in this case! I didn't have access to the hpp files you used apart from array.hpp
Let's start with some memory issues that your code is making
While initializing your array you are only initializing a single integer. But you need multiple integers in the array when you say want an array of size 5, you need to declare 5 integers. So you should declare an entire memory space for that. I am using malloc for this.
int* start = (int *)malloc(size*sizeof(int))
Secondly in your code for set there is a logical error that would change your start pointer from the original array which should not be happening. Instead you should just change the value at start.
*start = val;

Inserting new element on dynamic array of pointers to objects

I have a class representing an array, holding pointers to my other class objects.
#include "Edge.h"
class Array
{
private:
Edge** _headPtr;
int arraySize;
public:
Array(int);
void pushBack(Edge*);
// other functions...
};
Array::Array(int arraySize)
{
this->arraySize = arraySize;
this->_headPtr = new Edge*[arraySize];
}
Program always returns memory allocation errors after calling
// inserts an element on the end of the array
void Array::pushBack(Edge* element)
{
if (arraySize == 0) {
_headPtr = new Edge*[1];
_headPtr[0] = element;
arraySize++;
}
else {
Edge** _tempPtr = new Edge*[arraySize + 1]; // crashing here
memcpy(_tempPtr, _headPtr, arraySize * sizeof(Edge*));
//for (int i = 0; i < arraySize; i++) delete _headPtr[i];
delete[] _headPtr;
_tempPtr[arraySize] = element;
_headPtr = _tempPtr;
arraySize++;
}
}
I have commented out the for (int i = 0; i < arraySize; i++) delete _headPtr[i];
part because it was causing _free_dbg(block, _UNKNOWN_BLOCK); error.
From what I've found in other questions here I guess there must be a flaw in my understanding of dynamic array of pointers to class objects, but after spending much time trying to fix this I've run out of ideas.
The general idea of my program is to perform time efficiency measurements for some graph algorithms, this being part of Prim's algorithm implementation.
Call stack leading to this situation looks like this:
BinaryHeap queue = BinaryHeap();
queue.addNewElement(new Edge(v, v2, edgeWeight));
which looks like this
void BinaryHeap::addNewElement(Edge* element)
{
heapElements->pushBack(element);
heapFix_UP(heapElements->getSize()-1);
}
And finally pushBack method.
heapElements is Array* heapElements inside the BinaryHeap class, initialized with
heapElements = new Array(); in BinaryHeap constructor.
Edge is a very simple class holding only three integer values.
Please do not suggest using std::vector, the whole idea is not to use STL.
OK, I have found the solution. All of the code above works good, the bug was in a completely different place in my code.
What was so wrong that it was causing the whole program to crash many lines later?
This:
int** graphMatrix;
graphMatrix = new int*[vertex];
for (i = 0; i < edges; i++) graphMatrix[i] = new int[edges];
So simple, yet so harmful.
It is a part of my incidence matrix implementation. Now the reason for all crashes is pretty obvious - trying to write/read unallocated memory and causing heap corruptions.

Program crashes whenever i run the commented code

Whenever i run the commented part of the constructor money the program crashes.
When i compile it, it does not throw any error as well.
Can someone tell me what is happening?
Also i am trying to implement the vending machine problem here.
i have removed some parts of the code which are working properly.
#include <iostream>
using namespace std;
class money
{
public :
int *max;
int *accepted_values = new int[10];
bool present;
int *deposited;
int i;
money()
{
}
money(int *a, int how_many)
{
//*max = how_many;
// for (i=0; i<how_many; i++)
// {
// accepted_values[i] = a[i];
// }
//*deposited = 0;
present = false;
}
};
class Vending_machine
{
public :
money *coins = new money(accepted_coins, 5);
//money *coins = new money();
int *amount_deposited = new int;
Vending_machine()
{
cout<<"Cool";
}
~Vending_machine()
{
delete amount_deposited;
}
};
int main()
{
Vending_machine a;
}
You are dereferencing the int pointers int *max and int *depositedin your constructor, without assigning a proper memory address first.
This will always crash, since it's undefined behaviour.
int* myPointer;
*myPointer = 10; // crashes
A pointer has always to point to a valid address first, before you can use it.
This could be the address of another variable:
int myInt;
int *myPointer = &myInt;
*myPointer = 10; // doesn't crash - myInt now is 10.
or it could be dynamically allocated and released.
int* myPointer = new int;
But in that case you'll have to take care that the memory is released once you are done.
delete myPointer;
A better solution is to use std::unique_ptr<>, which takes care of releasing its pointer on destruction.
But the best solution is not to use pointers at all, if they are not really necessary - especially if you don't know very exactly how pointers work. I assume in your example you could avoid pointers completely.

C++ managing the dynamic allocation of your objects

I am trying to implement my own class Alloc which will help in the dynamic allocation of objects..
I want to keep track of the number of allocated objects in my program. So, each time a new instance of an object is allocated, the counter increments by one and decrements when an object is destroyed. When my program shuts down, if the counter is not at zero, the object prints an error message to the screen and has the program hang until the user hits enter..
This is what I have so far.. I hope you guys can help me to implement this..
class Alloc{
static int counter;
public:
Alloc(){ counter++; };
Alloc(int *d, static int size, const Alloc& c){
d=(int *) malloc(size*sizeof(int));;
//d=new int[size];
Alloc *my_alloc;
//my_alloc = new Alloc[size]; //note that the type is a Myclass pointer
for(int i=0; i<size; i++){
my_alloc[i] = new Alloc[size];
}
//for(int i=0; i < size; i++){
// d[i]=c.d[i];
//}
}
~Alloc(){ counter--; }
};
I know a lot is missing so, I will appreciate help and fixing mistakes too..
Thanks!!!
d=(int *) malloc(size*sizeof(int));;
d=new int[size];
The second line here is overwriting the d pointer with a second allocation, so the memory allocated by malloc is being lost!
If you really want to do it this way you need to use placement new, i.e. something like
d=(int *) malloc(size*sizeof(int));;
e=new (d) int[size];
though the details are quite tricky to get right.
To just count the number of objects in your programme though, there is a much easier option. Implement a templated "mixin" which contains a static counter for each type. Something like
template <typename T>
struct countable
{
countable() { _count++; }
countable(const countable&) { _count++; }
~countable() { _count--; }
static int get_count() { return _count; }
private:
static int _count;
};
and then having your objects inherit from this, as in
class MyClass : countable<MyClass>
{
// whatever
};
It's simple, and easy to turn into a no-op for release builds.
the track of number of instances of class say Alloc can also be kept as
class Alloc
{
Public:
static int Coounter; // object counter
// Constructor
Alloc(){
Counter++;}
// Destructor
~Alloc()
{
Counter--;
}
};
Simple, easy to use and maintainable

C++ Stack datastructure. What's wrong with this piece of code?

so I'm currently trying to migrate my Java experience to C++ by implementing various Data Structures for the sake of having them implemented at least once.
Would you mind giving me some advise? The problem I am having is mainly concentrated around the pointers in push(int value) and especially pop(). As push seems to be working correctly I found myself struggling to get the correct value back when pop'ing things. What's the matter?
PS: I also think, that since I allocate my array space manually I'd need to delete it aswell. How do I do that?
#ifndef STACK_H
#define STACK_H
class Stack
{
private:
int *stackArray;
int elementsInArray;
int allocatedArraySize;
int alpha;
int beta;
public:
Stack();
void push(int aValue);
int pop();
bool isEmpty();
int size() const;
};
#endif
and the implementation:
#include <iostream>
#include "Stack.h"
Stack::Stack()
{
alpha = 4;
beta = 2;
elementsInArray = 0;
allocatedArraySize = 1;
stackArray = new int[1];
}
void Stack::push(int aValue)
{
if (elementsInArray == allocatedArraySize)
{
int temporaryArray[allocatedArraySize*beta];
for (int i = 0; i < elementsInArray; i++)
temporaryArray[i] = stackArray[i];
stackArray = temporaryArray;
allocatedArraySize *= beta;
}
elementsInArray++;
stackArray[elementsInArray] = aValue;
}
int Stack::pop()
{
int result = -INT_MAX;
if (elementsInArray == 0)
return result;
if (elementsInArray > 0)
{
result = stackArray[elementsInArray-1];
elementsInArray--;
if (elementsInArray <= allocatedArraySize/alpha)
{
int temporaryArray[allocatedArraySize/alpha];
for (int i = 0; i < elementsInArray; i++)
temporaryArray[i] = stackArray[i];
stackArray = temporaryArray;
allocatedArraySize /= beta;
}
}
return result;
}
bool Stack::isEmpty()
{
if (elementsInArray == 0)
return true;
return false;
}
int Stack::size() const
{
return allocatedArraySize;
}
For starters, you should be post incrementing the index on the array, so change:
elementsInArray++;
stackArray[elementsInArray] = aValue;
to:
stackArray[elementsInArray++] = aValue;
or:
stackArray[elementsInArray] = aValue;
elementsInArray++;
Second, when you create the new temp array you are doing it inside the if statement... therefore it is a local variable and placed on the system stack and lost after you exit the if statement. So change
int temporaryArray[allocatedArraySize*beta];
to:
int *temporaryArray = new int[allocatedArraySize*beta];
Third, add in the delete you were talking about by saving the original pointer from stackArray before copying the location of tempArray and then perform the delete after you've made the pointer copy.
Finally, you'll have to make similar changes to your pop function...
You are using an array on the stack (not your stack - the program execution stack). It's the one called temporaryArray in your push function. The address of that array will be invalid when you return from that function (because other functions will use the stack to hold other data).
what you want to do is allocate that array on the heap. This is memory that stays around for your program as long as you need it. To do this, you would allocate your temporaryArray like
int * temporaryArray(new int[allocatedArraySize*beta]);
Then, after copying the elements from your old array, you would delete it by using:
delete [] stackArray;
Do this before assigning the stackArray with the temporaryArray.
There may be other issues with your data structure, but you are doing the basic indexing correctly and incrementing / decrementing the current index appropriately (though I would suggest preferring to use the preincrement / decrement forms when not using the temporary as a good habit to get in - ie. ++elementsInArray / --elementsInArray).
well, i'm sure you already know that you have stack as a generic (c++ call it templates) in the STD library. Assuming you are doing this as a code kata, i would start writing it as a template, so it can't take object types others than integers.
Also, if you are going to write more of these low-level structures (as part of your kata), write a thin class where you delegate all allocation, reallocation and allocated size tracking, and use that instead of using arrays directly.