I have an ordered arrayList. Where elements are to be ordered in 1,2,3,4,5,6.
At the moment the push function is not working. It will insert an element, but there is a problem which i cannot figure out. The push will work once you insert an incremented number... So like 1,2,3,4,5 but will not work once i insert like this 5,2,4,3,2,1.
Can anyone help me with this?
Here is my code:
Initialisation
template <class Datatype>
//--------------------------------------------------------------------------------------------
// Class: OrderedArray.
//--------------------------------------------------------------------------------------------
class OrderedArray
{
//--------------------------------------------------------------------------------------------
// Member Variables.
//--------------------------------------------------------------------------------------------
private:
Datatype* m_array;
int size;
int g_size;
int num_elements;
//---------------------------------------------------------------------------------------
// Name: Print Function:
// Description: To print out all elemenst in the Array.
//---------------------------------------------------------------------------------------
void print()
{
for(int i=0;i< size;i++)
{
cout << "Position: " <<m_array[i]<<endl;
}
}
//---------------------------------------------------------------------------------------
// Name: Resize Function:
// Description: To resize the Array.
//---------------------------------------------------------------------------------------
void Resize(int p_size)//resizes the array to the size of p_size
{
if(p_size < 0)//checks if new size is less than 0
{
cout << "ERROR! Size of an array can not be less than 0!" << endl;
}
else//else its ok to continue
{
Datatype* newArray = new Datatype[p_size];//creates a pointer newArray that points at a new array
if(newArray == 0)
return;
int min;
if(p_size < m_size)//checks the if the new array is smaller than the old one
min = p_size;
else//else its going to be bigger
min = m_size;
int index;
int temp = num_elements;//puts num_elements into a temporary variable called temp
num_elements = 0;//num_elements is set to 0
for(index = 0; index < min; index++)
{
newArray[index] = m_array[index];//places everything from the old array into the new array that will fit.
if(num_elements < temp)//if the num_elements is less than temp(the original num_elements)
{
num_elements++;//increment num_elements. This will keep incrementing to create the new num_elements based the number of elements cut off in the resize
}
}
m_size = p_size;//sets the old size to be equal to the new size
if(m_array != 0)
delete[] m_array;//deletes the old array
m_array = newArray;//makes m_array point at the new array
newArray = 0;//makes newArray a null pointer
}
}
//---------------------------------------------------------------------------------------
// Name: Push
// Description:
//---------------------------------------------------------------------------------------
void push(Datatype p_item)
{
if(num_elements == size)//checks if the array is full and needs to be resized
{
Resize(size + g_size);//calls the resize function
}
int pos = num_elements;
for(int x=0;x<num_elements;x++)
{
if(p_item < m_array[x])
pos=x;
break;
}
//loops through the array from high to low moving all values to the right
//to make space for the passed in value until it gets to the right place
for(int index = num_elements; index >= pos; index--)
{
m_array[index] = m_array[index-1];//moves the values to the right
}
m_array[pos] = p_item;//the passed in value is positioned into its ordered position
num_elements++;
cout<< "Num Elements " << num_elements;
cout<< "Size " <<size;
}
I think I found the beginning of the problem:
for(int x=0;x<num_elements;x++)
{
if(p_item < m_array[x])
pos=x;
}
your pos will always always be at the end of the array that way(assuming the array is properly sorted up to that point). add a break statement to let your loop know when it should stop assigning greater and greater values to pos
for(int x=0;x<num_elements;x++)
{
if(p_item < m_array[x])
{
pos=x;
break;
}
}
your code has some other issues too, for instance
for(int index = num_elements; index > pos; index--)
{
m_array[index] = m_array[index+1];//moves the values to the right
}
actually moves the values left. change the assignment to
for(int index = num_elements; index > pos; index--)
{
m_array[index] = m_array[index-1];//moves the values to the right
}
Related
In my Comp Sci class, we are learning how to make our own vector class. We will eventually store our custom made string class objects in a custom made vector class. I wanted to try and build a vector class of integers beforehand for simplicity.
So far, I have a default constructor that initializes my pointer to an empty array and sets the size to 0. Then I try to append some values using my push_back function and then check to make sure it was done correctly.
When I do std::cout << v[0] << std::endl;
I get the correct output (10). However, if I call push_back again and then call v[1] I get 0.
I feel like I am not allocating memory correctly in my push_back function but I am not sure.
Thanks for any advice!
[part 1][1]
[part 2][2]
sorry if my formatting is wrong I am new to posting here.
class:
class myVector
{
private:
int *data; //will point to an array of ints
size_t size; //determins the size of array
public:
myVector(); // default constructor
void push_back(int); // appends an integer to the vector
int operator[](size_t);
size_t sizeOf();
};
main:
int main()
{
myVector v;
v.push_back(10);
std::cout << v.sizeOf() << std::endl;
v.push_back(14);
std::cout << v.sizeOf() << std::endl;
std::cout << v[1] << std::endl;
return 0;
}
member functions:
size_t myVector::sizeOf()
{
return size;
}
int myVector::operator[](size_t location)
{
return this->data[location]; //this will return the value at data +
//location
}
myVector::myVector()
{
this->data = new int[0]; //initialize the data to an empty array of
//ints
size = 0; //initialize the size to 0
}
void myVector::push_back(int val)
{
if(size == 0) //if size == 0, create a new array with 1 extra index
{
++size;
delete [] this->data;
this->data = new int[size];
this->data[0] = val;
}
else
{
++size;
int *temp = new int[size - 1];
for(int i = 0; i != (size - 1); i++)
{
temp[i] = this->data[i];
}
delete [] this->data;
this->data = new int[size];
for(int i = 0; i != (size - 1); i++)
{
this->data[i] = temp[i];
}
this->data[size] = val;
delete [] temp;
}
}
In your code:
this->data[size] = val;
you are going outside of the allocated array.
Same in the previous loop (in its last iteration):
for(int i = 0; i != (size - 1); i++)
{
this->data[i] = temp[i];
}
There are a few problems.
It does not look like you need a special case for 0 sized vector
you do not allocate enough memory:
Example, if size is one, you hit this case, then size becomes 2, and you allocate a buffer of ... 1.
else
{
++size;
int *temp = new int[size - 1];
for(int i = 0; i != (size - 1); i++)
{
temp[i] = this->data[i];
}
Tip: use ```for (int i = 0; i < size; ++i)``` and ```new int[size]```
you go out of bounds after your loop. If you allocate [size] bytes, then (size-1) is the last valid index.
you copy data into temp, then copy temp into ANOTHER allocation. You don't need to do that. Just assign this->data = temp; The whole second loop is needless, and don't delete temp at the end.
Its not necessary to a lot of new and delete operations and loops. I fixed and cleaned your two functions.
myVector::myVector()
{
this->data = new int[1]; //initialize the data to an empty array of
//ints
size = 0; //initialize the size to 0
}
void myVector::push_back(int val)
{
if(size == 0) //if size == 0, create a new array with 1 extra index
{
++size;
this->data[0] = val;
}
else
{
++size;
int *temp = new int[size];
for(int i = 0; i != (size-1); ++i)
{
temp[i] = this->data[i];
}
delete [] this->data;
this->data = temp;
this->data[size-1]=val;
}
}
in push_back function allocate a new array with new size and copy data from existing array. After deleting existing array and we see this->data can't point to valid location. Assign the new array's address to this->data and we access existing data and size increased +1. Last we assign parameter val to end of array(size-1).
So I have to implement a stack using an array built in a class, and if the "stack" ever fills up, I am supposed to increase the size of the array which I attempted, and failed. So I am just curious as to what I need to change in order to make this work.
class AbstractStack
{
private:
Type elements; // elements in the array
Type max;
Type *s;
public:
AbstractStack(Type num) { //CONSTRUCTOR
elements= -1;
this->max = num;
s = new Type[max];
}
/* bunch of code that does not apply to this issue
*/
void push ( Type e ) {
if (elements + 1 == max) {
cout << "Stack at max size, WIll increase size of array and add item" << endl;
Type *temp = new Type[max + (max/2)];
for (int i = 0; i < elements+1; i++) {
temp[i] = s[i];
}
s = temp;
delete temp;
elements++;
s[elements] ;
return;
}
else {
elements++;
s[elements] = e;
}
}
When I take the size of this new s, I get the correct size of 1 larger than before because this function is only called when trying to add 1 element to the full stack, but when I attempt to use the top function, it just gives me 0 then I get like 50 lines of error codes starting in:
*** Error in `./a.out': double free or corruption (top): 0x0000000000c53cf0 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x7c619)[0x7fa34a270619]
./a.out[0x400c38]
./a.out[0x400b48]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7fa34a215c05]
./a.out[0x400979]
Type elements; // elements in the array
Type max;
These are both just ints, or unsigneds, or size_ts, or whatever you prefer for counting. They have nothing to do with Type whatsoever.
void push ( Type e ) {
if (elements + 1 == max) {
cout << "Stack at max size, WIll increase size of array and add item" << endl;
Type *temp = new Type[max + (max/2)];
After this you should increase max to max*3/2.
for (int i = 0; i < elements+1; i++) {
Loop condition should be i < elements. You are using element zero, and element[elements] does not exist yet.
temp[i] = s[i];
}
s = temp;
delete temp;
Last two lines should be delete[] s followed by s = temp.
elements++;
s[elements] ;
Last two lines should be s[elements++] = e;
return;
return is redundant here.
}
else {
elements++;
s[elements] = e;
Again, the last two lines should be s[elements++] = e;
}
}
Corrected and simplified version:
int elements;
int max;
// ...
void push ( Type e ) {
if (elements + 1 == max) {
cout << "Stack at max size, WIll increase size of array and add item" << endl;
max += max/2;
Type *temp = new Type[max];
for (int i = 0; i < elements; i++) {
temp[i] = s[i];
}
delete[] s;
s = temp;
}
s[elements++] = e;
}
You have to delete the old array (s) instead of the new (temp):
delete[] s;
s = temp;
Also: make sure that your class has a proper destructor (deleting s).
I have an ordered array list. And in my resize function I create a new array and assign it the values of the old array and then I delete the old array using delete[] arrayname;.
This causes an error at run-time whenever the resize function comes into play. dbgheap.c is called. Has anyone ever seen this before?
Here is my code:
//--------------------------------------------------------------------------------------------
// Name: OrderedArray.h.
// Description: Header file for the use in OrderedArray.cpp.
//--------------------------------------------------------------------------------------------
#ifndef ORDEREDARRAY_H
#define ORDEREDARRAY_H
#include <iostream>
using namespace std;
//--------------------------------------------------------------------------------------------
// Name: template <class Datatype>
// Description:
//--------------------------------------------------------------------------------------------
template <class Datatype>
//--------------------------------------------------------------------------------------------
// Class: OrderedArray.
//--------------------------------------------------------------------------------------------
class OrderedArray
{
//--------------------------------------------------------------------------------------------
// Member Variables.
//--------------------------------------------------------------------------------------------
private:
Datatype* m_array;
int size;
int g_size;
int num_elements; //Counter for the number of elements in the Array.
void Resize(int p_size)//resizes the array to the size of p_size
{
cout << "Did i get this far ";
if(p_size < 0)//checks if new size is less than 0
{
cout << "ERROR! Size of an array can not be less than 0!" << endl;
}
else//else its ok to continue
{
Datatype* newArray = new Datatype[p_size];//creates a pointer newArray that points at a new array
if(newArray == 0)
{
return;
}
cout << "Did i get this far ";
int min;
if(p_size < size)//checks the if the new array is smaller than the old one
min = p_size;
else//else its going to be bigger
min = size;
cout << "Did i get this far ";
int index;
int temp = num_elements;//puts num_elements into a temporary variable called temp
num_elements = 0;//num_elements is set to 0
for(index = 0; index < min; index++)
{
newArray[index] = m_array[index];//places everything from the old array into the new array that will fit.
if(num_elements < temp)//if the num_elements is less than temp(the original num_elements)
{
num_elements++;//increment num_elements. This will keep incrementing to create the new num_elements based the number of elements cut off in the resize
}
}
size = p_size;//sets the old size to be equal to the new size
cout << "Did i get this far ";
if(m_array != 0)
{
cout << "\nI am just about to delete ";
delete[] m_array;//deletes the old array
}
m_array = newArray;//makes m_array point at the new array
newArray = 0;//makes newArray a null pointer
}
}
//---------------------------------------------------------------------------------------
// Name: Push
// Description:
//---------------------------------------------------------------------------------------
void push(Datatype p_item)
{
if(num_elements == size)//checks if the array is full and needs to be resized
{
Resize(size + g_size);//calls the resize function
}
int pos = num_elements;
for(int x=0;x<num_elements;x++)
{
if(p_item < m_array[x])
{
pos=x;
}
}
//loops through the array from high to low moving all values to the right
//to make space for the passed in value until it gets to the right place
for(int index = num_elements; index >= pos; index--)
{
m_array[index] = m_array[index-1];//moves the values to the right
}
m_array[pos] = p_item;//the passed in value is positioned into its ordered position
num_elements++;
cout<< "Num Elements " << num_elements;
cout<< "Size " <<size;
}
//--------------------------------------------------------------------------------------------
// Name: Constructor.
// Description: Constructs the Array.
//--------------------------------------------------------------------------------------------
OrderedArray(int p_size, int grow_size)
{
//Sets the Array size.
m_array = new Datatype[p_size,grow_size];
size = p_size;
g_size = grow_size;
//How many elements are in the Array.
num_elements = 0;
}
//size and g_size are given its value by the user at the start of the program.
There may be some other issue here, but the most obvious thing I can see is this:
for(int index = num_elements; index >= pos; index--)
{
m_array[index] = m_array[index-1];
}
If pos happens to be zero, you will eventually do this:
m_array[0] = m_array[-1];
This problem will show immediately (when num_elements is zero - you haven't shown your constructor, but I do hope that you initialised everything).
Changing >= to > in the loop may solve all your troubles.
Conceptually, you ought to agree with this logic. There is no point moving the item before m_array[pos] forward to m_array[pos] when you are just about to replace it with the new item.
[edit] Now that you have posted your constructor:
m_array = new Datatype[p_size,grow_size];
This will initialise your array with the size grow_size instead of p_size, because of how the comma operator works. Read this: How does the Comma Operator work
Please do this instead:
m_array = new Datatype[p_size];
Your code m_array = new Datatype[p_size,grow_size]; in the constructor should only take one parameter which is the size of the array.
Change to this: m_array = new Datatype[p_size];
i am making an ordered array. Where the elements are in order. Example 1,2,3,4,5,6,77,89,100,201. I ask the user to enter in the size of the array. This is fine and the push function will put the elements in ordered. But when the arrayList is resized,The elements are no longer being allocated in an ordered fashion.
Here is my code:
//-------------------------------------------------------
// Name: Array::Resize
// Description: Resize the array to a new size.
// Arguments: p_size. The new size of the Array.
//-------------------------------------------------------
void Resize(int p_size)//resizes the array to the size of p_size
{
cout << "Did i get this far ";
if(p_size < 0)//checks if new size is less than 0
{
cout << "ERROR! Size of an array can not be less than 0!" << endl;
}
else//else its ok to continue
{
Datatype* newArray = new Datatype[p_size];//creates a pointer newArray that points at a new array
if(newArray == 0)
{
return;
}
cout << "Did i get this far ";
int min;
if(p_size < size)//checks the if the new array is smaller than the old one
min = p_size;
else//else its going to be bigger
min = size;
cout << "Did i get this far ";
int index;
int temp = num_elements;//puts num_elements into a temporary variable called temp
num_elements = 0;//num_elements is set to 0
for(index = 0; index < min; index++)
{
newArray[index] = m_array[index];//places everything from the old array into the new array that will fit.
if(num_elements < temp)//if the num_elements is less than temp(the original num_elements)
{
num_elements++;//increment num_elements. This will keep incrementing to create the new num_elements based the number of elements cut off in the resize
}
}
size = p_size;//sets the old size to be equal to the new size
cout << "Did i get this far ";
if(m_array != 0)
cout << "\nI am just about to delete ";
//delete[] m_array;//deletes the old array
m_array = newArray;//makes m_array point at the new array
newArray = 0;//makes newArray a null pointer
}
}
//---------------------------------------------------------------------------------------
// Name: Push
// Description:
//---------------------------------------------------------------------------------------
void push(Datatype p_item)
{
if(num_elements == size)//checks if the array is full and needs to be resized
{
Resize(size + g_size);//calls the resize function
}
int pos = num_elements;
for(int x=0;x<num_elements;x++)
{
if(p_item < m_array[x])
{
pos=x;
}
}
//loops through the array from high to low moving all values to the right
//to make space for the passed in value until it gets to the right place
for(int index = num_elements; index >= pos; index--)
{
m_array[index] = m_array[index-1];//moves the values to the right
}
m_array[pos] = p_item;//the passed in value is positioned into its ordered position
num_elements++;
cout<< "Num Elements " << num_elements;
cout<< "Size " <<size;
}
//--------------------------------------------------------------------------------------------
// Name: template <class Datatype>
// Description:
//--------------------------------
template <class Datatype>
//--------------------------------------------------------------------------------------------
// Class: OrderedArray.
//--------------------------------------------------------------------------------------------
class OrderedArray
{
//--------------------------------------------------------------------------------------------
// Member Variables.
//--------------------------------------------------------------------------------------------
private:
Datatype* m_array;
int size;
int g_size;
int num_elements; //Counter for the number of elements in the Array.
//--------------------------------------------------------------------------------------------
// Name: Constructor.
// Description: Constructs the Array.
//--------------------------------------------------------------------------------------------
OrderedArray(int p_size)
{
//Sets the Array size.
m_array = new Datatype[p_size];
size = p_size;
grow_size = 1;
//How many elements are in the Array.
num_elements = 0;
}
Any help would be much appreciated.
I suggest using copies of last element of your m as new elements instead of default-constructed instances. So the last elements will be grater or equal to all preceding elements of the array.
How can I make an inset method that will add a number into the array in the correct order?
void addElement(int table[], int element, int length) {
int x = 0;
int temporary=0;
cout<<length<<endl;
if(length == 1) {
table[0] = element;
}
else {
if(length == 2) {
if (table[0] > element) {
int temp = table[0];
table[0] = element;
table[1] = temp;
}
else {
table[1] = element;
}
}
else {
for(int i = 0; i< length && x == 0; i++) {
if(element<table[i] && element>=table[i-1]) {
for(int y = i; y<length; y++) {
temporary = table[y+2];
int temp = table[y];
table[y] = element;
table[y+1] = table
}
}
}
}
}
}
This is as far as I have gotten. In my main class I have worked it out so that array is increased by 1. So there is one open space at the end of the array for everything to be pushed back by 1.
You can scan the array from back to front, moving values up until you find the correct insertion point.
void addElement(int *table, int element, int length)
{
int i = length - 1;
for (; i > 0 && table[i-1] > element; --i)
{
table[i] = table[i-1];
}
table[i] = element;
}
Write a shiftElements function, write a findIndexOfFirstGreaterThan function, then in addElement - find the index, if -1 then put in last slot, else shift elements using index, then a[index]=elem;
Draw yourself an example, then work out a list of very simple steps required to do what you want.
Then write code that does those steps.
Im not sure if this is what your looking for, but I think you want something that adds an element depending on its integer value. Also, I do not have access to a compiler at this moment so there might be a couple of errors. The code below is just written to give you a brief idea of what you could do, but probably not a perfect solution to your problem.
int addElement (int element, int array [], int length)
{
vector <int> vectorOfInts; //vector to store current order of ints
vector <int> vectorOfArrangedInts; //vector to store arranged order
for (int counter = 0; counter < length; counter ++) //loop to fill the array with values
{
vectorOfInts.push_back (array [counter]);
}
for (int counter = 0; counter < vectorOfInts.length(); counter ++) //loop through all elements
{
int temp = 0; //stores temp value of biggest number found at a specific moment
int elementIndex; //stores indexes
for (int counterTwo = 0; counterTwo < vectorOfInts.length(); counterTwo ++) //loop through all elements to find the biggest array
{
if (vectorOfInts.at (counterTwo) >= temp) //if value is bigger than current biggest number
{
temp = vectorOfInts.at (counterTwo); //change temp value
elementIndex = counterTwo; //remember index
}
}
vectorOfArrangedInts.push_back (vectorOfInts.at(elementIndex)); //add the biggest number to the arranged values
vectorOfInts.erase (vectorOfInts.begin() + elementIndex); //remove the biggest element
}