I have read few topics about same problem, but i can't find what's wrong in my code. This is header file:
#pragma once
class Queue
{
private:
float *elements;
int count;
float newElement;
public:
Queue();
Queue(int);
Queue(Queue &);
~Queue();
void enqueue(float);
float dequeue();
int getCount();
};
And .cpp file:
#include "Queue.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
Queue::Queue()
{}
Queue::Queue(int arrSize)
{
this->count = arrSize;
float *elements = new float[arrSize];
for(int i = 0; i < arrSize - 1; i++)
{
newElement = rand()% 4000;
newElement /= 100;
elements[i] = newElement;
}
}
void Queue::enqueue(float element)
{
size_t newSize = count + 1;
float *new_elements = new float[newSize];
memcpy(new_elements, elements, newSize);
count = newSize;
delete [] elements;
elements = new_elements;
elements[count] = element;
}
float Queue::dequeue()
{
float firstElement = elements[0];
size_t newSize = count - 1;
float *new_elements = new float[newSize];
memcpy(new_elements, elements, newSize);
count = newSize;
delete [] elements;
elements = new_elements;
return firstElement;
}
int Queue::getCount()
{
return count;
}
Queue::~Queue()
{
delete [] elements;
}
int main(int argc, char *argv[])
{
srand(time(NULL));
Queue queue(4);
queue.enqueue(3);
}
I was trying to figure out where my mistake is, but I'm begginer in C++.
I think that something is wrong i my "dequeue" method, by after trying to fix it, it's still the same.
There are several problems
The default constructor doesn't initialize its members
Queue::Queue(int arrSize) has a local variable elements, which shadows the member elements. The consequence, this constructor doesn't initialize its member
enqueue should copy count * sizeof(float) bytes, not newSize bytes
as #Vladimir noticed, enqueue assigns one element beyond the allocated memory. Should be elements[count - 1] = element;
dequeue should copy newSize * sizeof(float) bytes, not newSize bytes
Related
i have this reSize function in my Array header
void reSize(int newsize) {
T* old = items;
size = newsize;
items = new T[newsize];
for (int i = 0;i < length;i++)
items[i] = old[i];
delete[]old;
}
and my main code:
struct User{
string name;
Array<int> data;
};
int main() {
Array<User> x(3);
x.get(0).name = "Kmal";
x.get(0).data.push_back(2); x.get(0).data.push_back(3);
x.reSize(10);
cout << x.get(0).data.get(0) <<endl;
return 0;
}
the problem is after resizing, my values that were stored in "data" variable are gone.
when i commented the code.
//delete[] old
in the reSize function
it worked fine...so i guess the problem is when i delete the pointer it deletes also the pointer inside the struct object which i don't want it to happen..
i don't want to comment the command becuz a leak in the memory will happen...how to fix this problem ?.
Update: My Array Class .
#include <iostream>
using namespace std;
template <class T>
class Array {
private :
T* items;
int size;
int length;
public :
Array() {
this->size = 0;
items = new T[this->size];
length = 0;
}
Array(int size) {
this->size = size;
items = new T[this->size];
length = 0;
}
int getsize() {
return this->size;
}
template <class T> void push_back(T x) {
if ((length+1) <= size) {
items[length] = x;
length++;
}
else {
this->reSize(size+1);
items[length] = x;
length++;
}
}
template <class T> void Insert(int index, T x) {
if (length + 1 <= size) {
for (int i = length;i > index;i--) {
items[i] = items[i - 1];
}
items[index] = x;
length++;
}
else {
this->reSize(size+1);
for (int i = length;i > index;i--) {
items[i] = items[i - 1];
}
items[length] = x;
length++;
}
}
template <class T> int Find(T x) {
int index = -1;
for (int i = 0;i < length;i++) {
if (items[i] ==x) {
index = i;
break;
}
}
return index;
}
void remove(int index) {
items[index] = "";
if(index+1 < length)
for (int i = index;i < length-1;i++) {
items[i] = items[i + 1];
items[i + 1] = "";
}
length--;
}
void reSize(int newsize) {
T* old = items;
size = newsize;
items = new T[newsize];
for (int i = 0;i < length;i++)
items[i] = old[i];
delete[]old;
}
void Merge(Array<T> x){
T* old = items; int oldlength = length;
items = new T[size + x.size];
size = size + x.size;
length += x.length;
for (int i = 0;i < length;i++) {
if(i< oldlength)
items[i] = old[i];
else
items[i] = x.items[i-oldlength];
}
delete[] old;
}
T& get(int index) {
return items[index];
}
}
struct User{
string name;
Array<int> data;
};
int main() {
Array<User> x(3);
// this line causes some problems
x.get(0).name = "Kmal";
x.get(0).data.push_back(2); x.get(0).data.push_back(3);
x.reSize(10);
cout << x.get(0).data.get(0) <<endl;
return 0;
}
In your code, declaring Array<User> x(3) declares an empty array with 3 elements that are preallocated. The length property of the array is 0. When the array is copied, length(0) elements are copied over into the resized storage. When you access the 0th element, it won't be copied on resize. What you actually need to do is call push_back() to add an element to the array so that length becomes 1 and the element is copied on resize.
Also, your array class is lacking a proper copy constructor and move constructor, which means copying it won't work at all. This means that User cannot be copied properly since it contains an array, which means that resizing an array of User won't work. You need to implement a copy constructor and copy assignment operator to be able to copy the array. You also need a destructor since, right now, the array is leaking memory when it goes out of scope.
I'm trying to make an ArrayList, an ADT object that uses dynamically allocated arrays to store data. It's supposed to mimic the vector class in that all I want the object to do is:
store data in a dynamically array
I want to define a default constructor (but I don't want to define any of the big three if I don't need to, and I don't think I need to)
have a working size function that returns the current size of the object's array, i.e the size of the list
an at() function
an insert(index, value) function
a remove(index) function
I keep getting leakage errors tho :(
I have attached my code for my header file, and a cpp file where I define my member functions. Does anyone think they can take a quick look at my code and tell me what I'm doing wrong?
header file:
#ifndef ARRAYLIST_H
#define ARRAYLIST_H
#include <cstdlib>
// declare class here
class ArrayList{
private:
int listSize;
int* arr;
public:
ArrayList();
int size() const;
int at(int index) const;
void insert(int index, int value);
void remove(int index);
};
#endif // ARRAYLIST_H
#include <stdexcept> //
#include "ArrayList.h"
// define class methods here
ArrayList::ArrayList() {
listSize = 0;
arr = new int[listSize];
}
int ArrayList::size() const{
return listSize;
}
int ArrayList::at(int index) const{
return arr[index];
}
void ArrayList::insert(int index, int value) {
// make a tempArr
// make listSize the listSize+1
// iterate through new tempArr and make it the same as arr until index is reached.
// at index, do tempArr[index] = value;
listSize++;
int* tempArr = new int[listSize];
for(int i = 0; i < listSize; i++){
if(i < index){
tempArr[i] = arr[i];
}
else if(i == index){
tempArr[index] = value;
}
else{
tempArr[i] = arr[i - 1];
}
delete [] arr;
arr = tempArr;
}
}
void ArrayList::remove(int index){
listSize--;
int* tempArr = new int[listSize]; // making a temporary dynamically allocated arr
for(int i = 0; i < listSize; i++){
if(i == index){ // skipping copying this element
continue;
}
tempArr[i] = arr[i];
delete [] arr;
arr = tempArr;
}
}
So I am trying to create a stack with a dynamic size, meaning that the capacity of the stack will change dynamically as needed. The concept worked out flawlessly in my head, create a function name memoryManagement(int i) that takes the size of data currently stored in the stack by a variable called usedCapacity. After this, the program was supposed to create a new array, use memcpy to copy the contents of the old array onto the new one. And finally, copy the contents of the new array back onto the old one with a new capacity. However, I keep getting a runtime error when I run my program. Also, depending in where I call the showStack function I sometimes get thrash numbers instead of the actual values I pushed onto the stack. If anyone could point me out on what I am doing wrong, I would greatly appreciate it.
#include <iostream>
#include <string>
#include <cstdlib>
#include <cstring>
using namespace std;
class Stack
{
public:
//stack functions
Stack();
void push(int a);
int pop();
int peek() const;
void showStack();
~Stack();
//memory management
void memoryManagement(int a);
//void setCapacity(int );
//void ensureCapacity(int minCapacity);
private:
int top;
int * arr;
int capacity;
int usedCapacity;
};
//////////////////////////////////////////////////////////////////////////////////
int main() {
Stack calc;
calc.push(11);
calc.push(33);
calc.showStack();
calc.push(23);
calc.push(43);
return 0;
}
//////////////////////////////////////////////////////////////////////////////////
Stack::Stack()
{
top = -1;
usedCapacity = 0;
capacity = 1;
arr = new int[capacity];
}
void Stack::push(int a)
{
if (top > capacity)
throw "Stack overflow";
top++;
usedCapacity++;
arr[top] = a;
memoryManagement(usedCapacity);
}
int Stack::pop()
{
if (top <= -1)
throw "Stack underflow";
arr[--top];
}
int Stack::peek() const
{
return top;
}
void Stack::showStack()
{
for (int i = 0; i < capacity; i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
Stack::~Stack()
{
delete[] arr;
}
void Stack::memoryManagement(int a)
{
if (a >= capacity)
{
int newCapacity;
newCapacity = (a * 3) / 2 + 1;
int * arr2 = new int[newCapacity];
memcpy(arr2, arr, sizeof(int) * usedCapacity);
delete[] arr;
arr = arr2;
delete[] arr2;
}
}
Why are you deleting arr2 from memoryManagement? You should not, as that's apparently your new class attribute (you did arr = arr2):
But that's not enough (your program will then start throwing exception upon push....because you also forgot to modify your capacity attribute. Here is your working memoryManagement function:
void Stack::memoryManagement(int a)
{
if (a >= capacity)
{
int newCapacity;
newCapacity = (a * 3) / 2 + 1;
int * arr2 = new int[newCapacity];
memcpy(arr2, arr, sizeof(int) * usedCapacity);
delete[] arr;
arr = arr2;
capacity = newCapacity; // Don't forget that!
//delete[] arr2; // Don't do that!
}
}
I am trying to overload Insert() method in C++. Here is my code which i had come up with
Below is my List.h file
#ifndef _LIST_H_
#define _LIST_H__
#include "stdafx.h"
#include <cstdlib>
#include <iostream>
class List
{
public:
List(size_t capacity = 5); // constructor - allocates dynamic array
~List(); // destructor
void insert(size_t position, int value);
void printArray();//Printing Array elements
private:
void resize(size_t new_size); // allocate new larger array
int *data_; // dynamic array
size_t size_; // size of dynamic array
size_t capacity_; // capacity of dynamic array
};
inline int& List::operator [] (size_t pos)
{
if (pos >= 0 && pos <= size_ - 1)
{
return data_[pos];
}
}
#endif _LIST_H_
This is my List.cpp file
#include "stdafx.h"
#include "List.h"
#include <iostream>
using namespace std;
List::List(size_t capacity)
{
data_ = new int[capacity];
capacity_ = capacity;
size_ = 0;
}
List::~List()
{
cout << "delete ";
delete[] data_;
}
void List::insert(size_t position, int value) {
if (size_ == capacity_)
{
resize(2 * capacity_);
}
if (position >= 0 && position <= capacity_ - 1)
{
data_[position] = value;
size_++;
}
}
void List::printArray()
{
size_t i;
for (i = 0; i < size_; i++)
{
cout << data_[i]<<" ";
}
}
void List::resize(size_t new_size)
{
int * temp;
size_t i;
capacity_ = new_size;
temp = new int[capacity_];
for (i = 0; i <= size_; ++i)
{
temp[i] = data_[i];
}
delete[] data_;
data_ = temp;
}
main method file
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
//List d,a;
List *arr,*temp;
arr = new List(10);
temp = new List();
arr->insert(1, 3);
cout << "Printing array list after inserting: " << endl;
arr->printArray();
}
Output:
Testing Insert method:
Printing array list after inserting:
-842150451
Expected:
Testing Insert method:
Printing array list after inserting:
3
suppose if i have array like arr =[1,2,3,4]; arr->insert(2,-2). Output should be arr= [1,2,-2,3,4]
Can any one tell me why it is displaying a random number instead of inserted value and How to modify the code
You should change this line:
arr->insert(1, 3);
into:
arr->insert(0, 3);
For my code, expand is to double the capacity of the vector. It should dynamically reallocate memory for the dynamically allocated array and update the value of capacity while not creating a memory leak.
I was wondering how you would check for a memory leak as my testing doesn't show execution times in Visual Studio.
void IntVector::expand(){
cap = cap * 2;
int *data2;
data2 = data;
IntVector::~IntVector();
data = new int[cap];
data = data2;
delete data2;
}
header (I understand that you aren't supposed to be using namespace std).
#ifndef INTVECTOR_H
#define INTVECTOR_H
using namespace std;
class IntVector{
private:
unsigned sz;
unsigned cap;
int *data;
public:
IntVector();
IntVector(unsigned size);
IntVector(unsigned size, int value);
unsigned size() const;
unsigned capacity() const;
bool empty() const;
const int & at (unsigned index) const;
const int & front() const;
const int & back() const;
~IntVector();
void expand();
};
#endif
main file
#include "IntVector.h"
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
IntVector::IntVector(){
sz = 0;
cap = 0;
data = NULL;
}
IntVector::IntVector(unsigned size){
sz = size;
cap = size;
data = new int[sz];
*data = 0;
}
IntVector::IntVector(unsigned size, int value){
sz = size;
cap = size;
data = new int[sz];
for(int i = 0; i < sz; i++){
data[i] = value;
}
}
unsigned IntVector::size() const{
return sz;
}
unsigned IntVector::capacity() const{
return cap;
}
bool IntVector::empty() const{
if(sz > 0){
return false;
}
else{
return true;
}
}
const int &IntVector::at(unsigned index) const{
if(index > sz){
exit(1);
}
else{
return data[index];
}
}
const int &IntVector::front() const{
return data[0];
}
const int &IntVector::back() const{
return data[sz];
}
IntVector::~IntVector(){
delete data;
}
void IntVector::expand(){
cap = cap * 2;
int *data2;
data2 = data;
IntVector::~IntVector();
data = new int[cap];
data = data2;
delete data2;
}
Edit::
void IntVector::expand(){
cap = cap * 2;
int *data2 = data;
data = new int[cap];
delete[] data2;
delete data2;
}
These 2 lines:
data = new int[cap];
data = data2;
Allocate an array of ints, and then immediately override the pointer leading to it, thereby losing that allocated memory for ever. That's a memory leak.
Using valgrind or similar tools should lead to these errors very easily.
To test for memory leaks in Visual Studio:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
and this next line will automatically display a memory-leak report at every place in your code where an application exit occurs.
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
Edited for maxywb
I use task manager from windows.
in windows 8:
Details tab -> right click on a column and 'select columns' -> GDI objects
Keep an eye on this column, if this keeps rising while it shouldn't then you have a leak.