Program Gives An Error Every Time After Working Once - c++

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;

Related

How to create a dynamic array within a C++ template class

I am having issues working with Templates within C++. In this case, I am trying to create a dynamic array that works with Templates. Disclaimer: This is a school assignment. I have tried working on it for several days now. I didn't get stuck on this part until Friday night, and my professor and the tutoring lab are not available during weekends.
We're learning about Vectors by creating a vector abstract data type and coding some of the methods. I can't use any directives besides iostream.
I'd appreciate if you could also explain the issue I am having and/or point me to resources regarding this topic. I've looked at a few videos on YouTube and Udemy, and I have also checked posts on this website or similar forums, but I have not been able to figure it out.
I've reduced the code a bit to keep the relevant sections without clutter.
Edit: Sorry, I added all of that writing and realized I forgot to add the actual issue I'm having. The dynamic array in the resize function (VectorADTcpp.h) throws errors when I try to initialize the tempArray. It also does not let me copy the contents of the dataArray to the new array - it throws the error "Cannot convert T to Class". Also, I know using std::vector is the better method, but as I stated, this is a homework problem I am having an issue with. Most of the code was given to us and we have to fill in the functions, so I am limited to the changes I can make.
VectorADT.h (Given)
#include <iostream>
#include <memory>
template <class T>
class VectorADT {
int SIZE = 2;
private:
T ** dataArray = nullptr;
int count;
public:
// default constructor
VectorADT();
// double the size of the database by
// creating another database twice the size and copying
// the existing database into it. The existing one is then deleted
void resizeADT();
// returns true if database is empty, false otherwise
bool empty();
// returns the number of items in the database
int size() const;
// inserts at the proper position, no sorting necessary
// element is inserted at index =pos
int insert(T * v, int pos);
// deletes the item at index position =pos
int remove(int pos);
};
VectorADTcpp.h
#include <iostream>
#include "VectorADT.h"
template <class T>
VectorADT<T>::VectorADT() {
dataArray= new T*[SIZE];
count=0;
}
template <class T> // Not Given
void VectorADT<T>::resizeADT(){
this->SIZE *= 2;
T tempArray = new T[this->SIZE];
for (int i = 0; i < count; i++)
{
tempArray[i] = this->dataArray[i];
}
tempArray = this->dataArray;
delete []this->dataArray;
this->dataArray = new T * [this->SIZE];
for (int i = 0; i < count; i++)
{
this->dataArray[i] = tempArray[i];
}
delete []tempArray;
}
remove method within VectorADTcpp.h that I had to code
template <class T> // Not Given
int VectorADT<T>::remove(int pos){
int adjustSteps=0;
if (pos < SIZE) {
for (int i = pos; i < count; i++)
{
dataArray[pos] = dataArray[pos + 1];
adjustSteps++;
}
}
else {
throw new std::string("Index out of bounds");
exit(-1);
}
return adjustSteps;
}

How to avoid a destructor being called twice in C++?

I'm testing out a class representing an dynamic array data structure I made for myself as practice with the language, but I ran into a problem where the destructor is called twice over, causing a heap corruption error.
So far, I have attempted to comment out some of the delete words. However, this leads to undefined behavior.
#include <iostream>
#include "windows.h"
#include <vector>
template<typename T> class Spider {
private:
T** pointer;
int maxSize;
int lengthFilled;
public:
//default constructor
Spider()
{
pointer = new T * [1];
maxSize = 1;
lengthFilled = 0;
}
//destructor
~Spider()
{
for (int i = 0; i < lengthFilled; i++)
{
pop();
}
delete[] pointer;
}
//Pushes an object in
void push(T thing)
{
if (lengthFilled == maxSize)
{
increaseSize();
}
T* thinggummy = &thing;
//then save its pointer in the functional array
pointer[lengthFilled] = thinggummy;
lengthFilled++;
}
//pops the array
void pop()
{
delete pointer[lengthFilled-1];
setSize(lengthFilled - 1);
lengthFilled--;
}
}
int main()
{
Spider<Spider<int>> test((long long)1);
for (int i = 0; i < 2; i++)
{
test.push(Spider<int>());
test.get(i).push(2);//this is implemented in the actual code, just omitted here
std::cout << test.get(i).get(0);
std::cout << "push complete\n";
}
system("pause");
return 0;
}
The expected results for this program should be:
2
push complete
2
push complete
Press any key to continue...
Instead, I get an critical error code in the debug log of "Critical error detected c0000374".
There are two issues here:
Like WhiteSword already mentioned, you are taking the address of a local variable when you do T *thinggummy = &thing. That is going to cause trouble since that address will be invalid as soon as you leave scope (unless maybe T resolves to a reference type).
You call delete on the things in the pointer array. However, these were not allocated via new. Instead they are just addresses of something. So you are trying to free something that was never allocted.

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++ 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.

Memory allocator causing mysterious pause

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.