Setting constructor and destructor with *pointer array C++ - c++

I am using int *studentsAge to store a list of ages, and double *marks[2] to store a list of 2 marks per student.
Basically, I am not sure how to set my constructor and destructor.
This is my constructor...
Students::Students()
{
num = 0;
studentsAge = NULL;
marks[2] = NULL;
}
I use both pointer arrays in this function...
void Students::storeValues(int num)
{
this->num = num;
studentsAge = new int[num];
for(int i=0; i<num; i++)
{
studentsAge[i] = i;
marks[i] = new double[num]
}
}
This is my destructor...
Students::Students()
{
for(int i=0; i<num; i++)
{
delete[] marks[i];
delete[] studentAge[i];
}
delete[] marks;
delete[] studentAge
}
I am not sure if my constructor and destructor are right and I can suspect a memory leak somewhere. I am not too good with pointers, but I would appreciate it if someone could tell me where I am going wrong

It's a better design to keep each student together:
struct Student
{
int marks[2];
int age;
};
Then store a container of students:
struct Students
{
std::vector<Student> students;
void storeValues(int num);
}
Your function would look like:
void Students::storeValues(int num)
{
students.resize(num, Student()); // zero-initialized students!
for(int i=0; i<num; i++)
students[i].age = i;
}
This way you do not need to write any destructors, or any other functions in the Rule of Five, so you reduce the opportunity to make errors and avoid wasting time writing boilerplate code.

There's no reason to use your 2 element array of marks. make it easy on yourself and change it to 2 double*'s marks0 and marks1.
double* marks0;
double* marks1;
However if you want to continue on the current path, first you need to initialize marks correctly:
Students::Students()
{
num = 0;
studentsAge = NULL;
marks[0] = NULL; //clear the pointer to the first array of marks
marks[1] = NULL; //clear the pointer to the second array of marks
}
Now you need to create the marks arrays correctly:
void Students::storeValues(int num)
{
this->num = num;
studentsAge = new int[num];
marks[0] = new double[num];
marks[1] = new double[num];
for(int i=0; i<num; i++)
{
studentsAge[i] = i; //what is this doing? each student's age is the same as his/her index?
marks[0][i] = 0; //initialize the first mark for student i
marks[1][i] = 0; //initialize the second mark for student i
}
}
Finally you need to destroy the arrays correctly:
Students::~Students()
{
delete[] marks[0];
delete[] marks[1];
delete[] studentsAge;
}

I am guessing your Students class looks a bit like this as far as your main fields are concerned:
class Students
{
private:
static const int maxNumberMarks = 2; //the maximum number of marks that can be stored per student
int numStudents; // the count of the number of students
int* studentsAge; // an array of each students ages
double* marks[maxNumberMarks]; // an array of arrays to store each student mark
}
In which case your default constructor is almost right. You just needed to initialise your marks array correctly.
Students::Students()
{
num = 0;
studentsAge = NULL;
for( int markIndex = 0; markIndex < maxNumberMarks; ++markIndex )
{
marks[markIndex ] = NULL;
}
}
Your initialisation function is a bit more confused.
First off I would rename the input num arg to something like numStudents so as to not get confused with the member variable of the same name.
Secondly you need to separate the allocation of your arrays from initialising them
void Students::storeValues(int numStudents )
{
this->num = numStudents ; //store off how many students we are handling.
//allocate 3 storage arrays for each student. The age array and 2 mark arrays
studentsAge = new int[numStudents ];
for( int markIndex =0; markIndex < maxNumberMarks; ++markIndex)
{
marks[markIndex] = new double[numStudents];
}
//now init the arrays to something
for(int studentIndex=0; studentIndex < numStudents ; studentIndex++)
{
studentsAge[studentIndex] = studentIndex;
for( int markIndex =0; markIndex < maxNumberMarks; ++markIndex)
{
marks[markIndex][studentIndex] = 0.0; //zero seems a reasonable initial value.
}
}
}
Finally to get the destructor you just need to mirror the code that allocated the arrays.
~Students()
{
//delete the marks arrays
for( int markIndex =0; markIndex < maxNumberMarks; ++markIndex)
{
delete[] marks[markIndex];
marks[markIndex] = NULL;
}
//delete the ages array
delete[] studentsAge;
studentsAge = NULL;
}
As your code grows it likely you will want to store different data for each student I would recommend creating a Student class to help simplify everything.
class Student
{
private:
static const int maxNumberMarks = 2; //the maximum number of marks that can be stored per student
int age; //the age of the student
double marks[maxNumberMarks];
}
Assuming you flesh out the Student array with appropriate Default constructor this simplifies all the many allocations to just one place in the Students class
Students
{
Student* studentsArray; //dynamically allocated array of student info
int numStudents;
}
void Students::storeValues(int numStudents )
{
this->num = numStudents ;
studentsArray = new Student[numStduents];
}
~Students()
{
delete[] studentsArray;
studentsArray = NULL;
}
And if you use the std::vector in place of the allocated array you don't even need to worry about allocating and freeing that.

Short answer:
You need to write the following:
Students::Students()
{
num = 0;
studentsAge = NULL;
marks[0] = NULL;
marks[1] = NULL;
}
void Students::storeValues(int num)
{
this->num = num;
studentsAge = new int[num];
marks[0] = new int[num];
marks[1] = new int[num];
for(int i=0; i<num; i++)
{
studentsAge[i] = i; // this is where you give each student an age, are you sure you want to use i?
// here you can put grade assignments as follows:
marks[0][i] = val1; // first mark for student i
marks[1][i] = val2; // second mark for student i
}
}
Students::~Students()
{
delete[] marks[0];
delete[] marks[1];
delete[] studentsAge;
}
Long answer:
It seems that you need to understand what a pointer is and what an array is.
When you put double *marks[2] in the class declaration, it'll reserve an array of size 2 of double
pointers attached to each instance of the class. You don't need to put the [2] in the constructor.
A pointer is a variable holding the first address of a block of reserved addresses in memory. This means when you assign to a pointer, you need to give it a memory address. To write a value to the address stored in a pointer, you use the * character before the variable.
int num = 2;
int* p;
p = &num; // p will hold the address of num. Any changes to p's value will be reflected in num
p = new int; // p is assigned a new address
*p = num; // the address that p points to will hold 2 (the value in num), but if that value is changed, num will still hold 2
If you wanted to assign an array to p, you would use the new keyword. This will allocate memory
for your program to use. Don't forget to deallocate it.
size = 10;
p = new int[size];
Now you can reference the values in p by treating it as an array or pointer arithmetic,
which I won't go into now.
p[0] = 1; // the first
p[5] = 56;
The difference between a pointer and an array is array allocation and deallocation is handled by the
compiler and needs to have a fixed size at compile time. Pointer allocation and deallocation is handled by the user and its size is defined at runtime.

Related

Appending a dynamic array and doubling its size upon completion

Create a dynamic array of int with a initial space of 4. Write a function ‘append’ that appends a given value to this array. At any stage, if this function finds the array full it automatically doubles the size of array to accommodate this new value. Also write a function to display all the elements of this array. Write a main to test all these functions.
I made an attempt to solve the above question as given below. However, I am unable to get the correct code. Please help me
#include<iostream>
using namespace std;
void append(int*& array, int val, int n, int r)
{
int i,p;
int *array1;
for (i=r;i<n;i++)
array[i] = val;
if(i==n)
{
p = 2*n;
array1 = new int [p];
}
for(int j =0; j<r/2; j++)
array1[j]= array[j];
append(array1, val, p, p/2);
}
int main()
{
int q,p=0,val, n = 4;
int n1 = p/2;
int *array = new int[n];
while(1)
{
cout<<"Enter 0 to end and 1 to continue";
cin>>q;
while(q!=0)
{
cin>>val;
append(array,val,n,n1);
}
}
return 0;
}
I need to solve this without using "Classes". How shall I do it?
Your function needs to do the following:
1) Be able to check if the current append call will result in an out-of-bounds write attempt. So you need something like (and give variables explanatory names like this) this as the first line in your function:
if (array_size < item_count) {
//double size of array
}
To double the size of the array, you have to make a new array with twice the size, copy all the items over from the old array, DELETE the old array, null the old array's pointer, and somehow update the array_size variable (return to main is one option, a static int counter in the function itself is another). You may have to return a pointer to the new array to main, as well. Or maybe you can just re-address the old pointer to the new array AFTER using that pointer to delete the old array. This is all about avoiding memory leaks. So, try to come up with a method declaration like:
int append(int* arrPtr, int value, int array_size, int item_count)
This particular approach means main is getting sent back the array size as an int after each append. So you need something in main like:
array_size = append(array, val, array_size, item_count);
The tricky part will be when you make the new array:
array_size = 2 * array_size;
int* temp = new int[array_size]
//copy everything over from old array to new using arrPtr and temp
for (int i = 0; i < array_size / 2; i++) {
temp[i] = arrPtr[i]
}
//delete the contents of the old array:
delete[] arrPtr;
//pointer gymnastics to redirect arrPtr to the new array:
arrPtr = temp;
temp = nullptr;
//okay, now you are back out of the conditional and can use item_count to insert the
//value into the array (doubled or not)
arrPtr[item_count] = value;
//don't forget to return array_size, and remember main must track item_count as well.
return array_size;
That's the general gist of it. This is not a complete answer, but should give you enough to work with. Basically, most of your code has to be rewritten, and the above is not a complete solution. Good luck.
After taking cue from Double size of dynamic array I have solved it.
#include<iostream>
using namespace std;
void add_element(int* &array, int &size)
{int count = 0;
while(1)
{
int number;
cout << "What number do you want to add? " << endl;
cin >> number;
if (count == size)
{
int newSize = size * 2;
int *newArr = new int[newSize];
for (int i = 0; i < count; ++i)
{
newArr[i] = array[i];
}
delete[] array;
array = newArr;
size = newSize;
}
array[count] = number;
++count;
int k;
cout<<"Do u want to end, then press 0";
cin>>k;
if(k==0) break;
}
for(int g = 0; g<count; g++)
cout<<array[g]<<'\t';
}
int main()
{
int i,j,k,size;
cin>>size;
int* array = new int [size];
add_element(array, size);
}

Errors with dynamic Array created with new after passed to resize function

I am trying to implement a dynamically created array using new that I want to resize but the resize action is not working correctly.
This is an exercise on dynamic arrays, so I need dynamic arrays using new and not std::vector.
Here is my code :
int main ()
{
// Build an application here
int length = 0;
int size = 0;
int input;
bool endAdding = false;
cout << "Please enter the length of the new array : ";
cin >> length;
int* oPtrDynamicArray = CreateDynamicArray (length, size);
do
{
cout << "Add an element (0 to quit) : " << endl;
cin >> input;
cout << endl << endl;
if (input == 0){
endAdding = true;
}
else
{
InsertElement(oPtrDynamicArray, input, size, length);
}
cout << "The array contains : " << endl;
for (int i = 0; i < size; i++)
{
cout << i << ": [" << oPtrDynamicArray[i] << "]" << endl;
}
} while (!endAdding);
DeleteDynamicArray (oPtrDynamicArray, size);
}
int *CreateDynamicArray (int capacity, int &size)
{
size = 0;
return new int[capacity];
}
void DeleteDynamicArray (int *dynamicArray, int &size)
{
delete[] dynamicArray;
dynamicArray = nullptr;
size = 0;
}
void InsertElement (int *dynamicArray, int element, int &size, int capacity)
{
if (capacity <= size)
{
ResizeDynamicArray (&dynamicArray, size+1);
}
dynamicArray[size] = element;
size++;
}
void ResizeDynamicArray (int **dynamicArray, int newCapacity)
{
int ** newArray = new int*[newCapacity];
for (int i = 0; i < newCapacity; i++)
{
newArray[i] = dynamicArray[i];
}
*dynamicArray = *newArray;
delete[] newArray;
newArray = nullptr;
}
The problem is that the array is passed to my InsertElement() function and then to ResizeDynamicArray() only if capacity <= size, but the array passed to the first function, is passed with good values, but with abnormal pointers in the array.
Example :
For an array of 3, I have :
array[0] = 1 --> adress 0x0004e300 containing value 1
array[1] = 2 --> adress 0x00000003 containing ???
array[2] = 3 --> adress 0x008ffb24 containing value 2
I really don't understand, it would be really great if someone could explain my error :/.
The problem is here
void InsertElement (int *dynamicArray, int element, int &size, int capacity)
{
if (capacity <= size)
{
ResizeDynamicArray (&dynamicArray, size+1);
}
dynamicArray[size] = element;
size++;
}
when you call ResizeDynamicArray you are changing the dynamicArray pointer declared as a parameter to InsertElement. You are not changing the oPtrDynamicArray pointer in main.
If you want to make this work you need to change InsertElement to take a double pointer (just like ResizeDynamicArray)
void InsertElement (int **dynamicArray, int element, int &size, int capacity)
{
if (capacity <= size)
{
ResizeDynamicArray (dynamicArray, size+1);
}
(*dynamicArray)[size] = element;
size++;
}
Or you could do the easy thing and just use std::vector<int>.
EDIT now that I look at it your ResizeDynamicArray function I see that function is completely wrong as well. It's clear that you have some learning to do with pointers
Here's how ResizeDynamicArray should be
void ResizeDynamicArray (int **dynamicArray, int newCapacity)
{
int * newArray = new int[newCapacity];
for (int i = 0; i < newCapacity; i++)
{
newArray[i] = (*dynamicArray)[i];
}
delete[] *dynamicArray;
*dynamicArray = newArray;
}
You're not the first newbie to fail to understand pointers. Have a good look at the code above and compare it with your code. The main difference is that my code using a pointer to change what is being pointed to. Your code tried to change the pointer itself, which is incorrect. It's confusing because what is being pointed to is another pointer (the dynamic array).
There are several issues in your code:
First, in ResizeDynamicArray, you allocate an array of pointers to ints, not an array of ints. int ** newArray = new int*[newCapacity] should be int *newArray = new int[newCapacity].
Second, once you have fixed that, you need to write *dynamicArray = newArray;;
but you should free the old array before you assign the pointer to the new memory block.
void ResizeDynamicArray (int **dynamicArray, int newCapacity)
{
int *newArray = new int[newCapacity];
for (int i = 0; i < newCapacity; i++)
{
newArray[i] = (*dynamicArray)[i];
}
delete[] *dynamicArray;
*dynamicArray = newArray;
}
Third, you since InsertElement may call ResizeDynamicArray (which will give you back a new memory block), you need to alter the originally passed pointer. So you need to pass a pointer to a pointer int the function, just as you did with ResizeDynamicArray:
void InsertElement (int **dynamicArray, int element, int &size, int capacity)
adapt the body accordingly then.
I know the question is already answered but not the why.
You have to keep in mind that pointers are passed to functions by value.
The pointer value, the address it points to, is lost when the function ends.
But you are still able to change the value stored at the address it points to by dereferencing the pointer.
To pass be able to change the pointer value, the address it points to, inside a function, you have to pass a pointer to a pointer. In this case passing a double pointer is synonym for passing a pointer to a function by reference.
void Foo(int **ptr)
{
// Don't use ptr, changes are lost after function end as ptr is a local copy
// Use *ptr to change the value of the pointer you passed to the function.
// Use **ptr to change the value at the address the pointer you passed to the funcion points to
}
In this case you can change the pointer value, the address it points to, by dereferencing the double pointer once. Which applies to above answers.

Resizing string array in hash-table

I'm learning hashing right now. I am trying to resize my hash-table when it is >=80% filled. But every time i try to resize it, i get undefined behaviour or it crashes.
I tried to make a new String array with more fields and then i deleted the old one but that wasn't working.
hashtable.h
class hashtable
{
public:
hashtable();
void insert(string);
void resize_array();
int hashfunction(string str);
string* getArray();
private:
int elemts_in_array;
int table_size;
string* T;
};
hashtable.cpp
hashtable::hashtable()
{
// your code (start with a capacity of 10)
table_size = 10;
elemts_in_array = 0;
string *array = new string[table_size];
T = array;
}
void hashtable::insert(string key)
{
string* array = getArray();
int hkey=hashfunction(key);
float filled = float(elemts_in_array)/float(table_size);
// When the array is more than 80% filled resize it and double the table_size
if(filled >= 0.8)
{
cout << "Resizing Array.." << endl;
resize_array();
}
for(int i=0; i<table_size;i++)
{
// if the field is empty insert it, else go +1
if(array[(hkey+i)%table_size] == "")
{
array[(hkey+i)%table_size] = key;
elemts_in_array++;
break;
}
if(array[(hkey+i)%table_size] == key)
{
// it is the same element
break;
}
}
}
void hashtable::resize_array()
{
int old_table_size =table_size;
table_size*=2; // double the size of the hashtable
string* old_array= new string[table_size]; // save the old array entries
old_array = T;
// Apply the old entries in old_array
for(int i=0; i<table_size;i++)
{
old_array[i]= T[i];
}
//create a new array with double size
string *new_array = new string[table_size];
//delete the old T
delete[] T;
T = new_array;
//re-hash the old entries into the new array with double size (HERE I GOT THE ISSUES)
for(int i=0; i<table_size/2; i++)
{
insert(old_array[i]);
}
}
sometimes my program went into a loop or it crashed. I really don't know why it is not working.
If you step through your program's execution with your debugger, you will probably spot an issue with your resize_array function.
When it copies the old table entries back to the newly allocated array, it uses the insert function. This has some problems:
you might not get back the same ordering of the original values, due to the collision resolution;
the insert function increases the table size, thus it will end up thinking it has twice as many entries as you originally inserted.
Now, the crash could happen because insert will hit the table-increase limit again. The cycle repeats until you either get a stack overflow or you run out of memory.
The proper way to copy back in your strings is this:
for(int i = 0; i < table_size / 2; i++)
{
T[i] = old_array[i];
}
But then there's another problem that can crash before any of this happens. You first saved your values like this:
for(int i=0; i<table_size;i++)
{
old_array[i]= T[i];
}
Note that table_size has already been doubled and so you are going to access past the end of T. You should have looped on old_table_size instead.
You also have some needless copying. If you are going to reallocate T, then just do this:
void hashtable::resize_array()
{
int old_table_size = table_size;
table_size *= 2;
string* old_T = T;
T = new string[table_size];
for (int i = 0; i < old_table_size; i++)
{
std::swap(T[i], old_T[i]); // or in C++11 assign with std::move
}
delete[] old_T;
}

C++ pointer to int in loops?

Ok, so I'm quite new to C++ and I'm sure this question is already answered somewhere, and also is quite simple, but I can't seem to find the answer....
I have a custom array class, which I am using just as an exercise to try and get the hang of how things work which is defined as follows:
Header:
class Array {
private:
// Private variables
unsigned int mCapacity;
unsigned int mLength;
void **mData;
public:
// Public constructor/destructor
Array(unsigned int initialCapacity = 10);
// Public methods
void addObject(void *obj);
void removeObject(void *obj);
void *objectAtIndex(unsigned int index);
void *operator[](unsigned int index);
int indexOfObject(void *obj);
unsigned int getSize();
};
}
Implementation:
GG::Array::Array(unsigned int initialCapacity) : mCapacity(initialCapacity) {
// Allocate a buffer that is the required size
mData = new void*[initialCapacity];
// Set the length to 0
mLength = 0;
}
void GG::Array::addObject(void *obj) {
// Check if there is space for the new object on the end of the array
if (mLength == mCapacity) {
// There is not enough space so create a large array
unsigned int newCapacity = mCapacity + 10;
void **newArray = new void*[newCapacity];
mCapacity = newCapacity;
// Copy over the data from the old array
for (unsigned int i = 0; i < mLength; i++) {
newArray[i] = mData[i];
}
// Delete the old array
delete[] mData;
// Set the new array as mData
mData = newArray;
}
// Now insert the object at the end of the array
mData[mLength] = obj;
mLength++;
}
void GG::Array::removeObject(void *obj) {
// Attempt to find the object in the array
int index = this->indexOfObject(obj);
if (index >= 0) {
// Remove the object
mData[index] = nullptr;
// Move any object after it down in the array
for (unsigned int i = index + 1; i < mLength; i++) {
mData[i - 1] = mData[i];
}
// Decrement the length of the array
mLength--;
}
}
void *GG::Array::objectAtIndex(unsigned int index) {
if (index < mLength) return mData[index];
return nullptr;
}
void *GG::Array::operator[](unsigned int index) {
return this->objectAtIndex(index);
}
int GG::Array::indexOfObject(void *obj) {
// Iterate through the array and try to find the object
for (int i = 0; i < mLength; i++) {
if (mData[i] == obj) return i;
}
return -1;
}
unsigned int GG::Array::getSize() {
return mLength;
}
I'm trying to create an array of pointers to integers, a simplified version of this is as follows:
Array array = Array();
for (int i = 0; i < 2; i++) {
int j = i + 1;
array.addObject(&j);
}
Now the problem is that the same pointer is used for j in every iteration. So after the loop:
array[0] == array[1] == array[2];
I'm sure that this is expected behaviour, but it isn't quite what I want to happen, I want an array of different pointers to different ints. If anyone could point me in the right direction here it would be greatly appreciated! :) (I'm clearly misunderstanding how to use pointers!)
P.s. Thanks everyone for your responses. I have accepted the one that solved the problem that I was having!
I'm guessing you mean:
array[i] = &j;
In which case you're storing a pointer to a temporary. On each loop repitition j is allocated in the stack address on the stack, so &j yeilds the same value. Even if you were getting back different addresses your code would cause problems down the line as you're storing a pointer to a temporary.
Also, why use a void* array. If you actually just want 3 unique integers then just do:
std::vector<int> array(3);
It's much more C++'esque and removes all manner of bugs.
First of all this does not allocate an array of pointers to int
void *array = new void*[2];
It allocates an array of pointers to void.
You may not dereference a pointer to void as type void is incomplete type, It has an empty set of values. So this code is invalid
array[i] = *j;
And moreover instead of *j shall be &j Though in this case pointers have invalid values because would point memory that was destroyed because j is a local variable.
The loop is also wrong. Instead of
for (int i = 0; i < 3; i++) {
there should be
for (int i = 0; i < 2; i++) {
What you want is the following
int **array = new int *[2];
for ( int i = 0; i < 2; i++ )
{
int j = i + 1;
array[i] = new int( j );
}
And you can output objects it points to
for ( int i = 0; i < 2; i++ )
{
std::cout << *array[i] << std::endl;
}
To delete the pointers you can use the following code snippet
for ( int i = 0; i < 2; i++ )
{
delete array[i];
}
delete []array;
EDIT: As you changed your original post then I also will append in turn my post.
Instead of
Array array = Array();
for (int i = 0; i < 2; i++) {
int j = i + 1;
array.addObject(&j);
}
there should be
Array array;
for (int i = 0; i < 2; i++) {
int j = i + 1;
array.addObject( new int( j ) );
}
Take into account that either you should define copy/move constructors and assignment operators or define them as deleted.
There are lots of problems with this code.
The declaration void* array = new void*[2] creates an array of 2 pointers-to-pointer-to-void, indexed 0 and 1. You then try to write into elements 0, 1 and 2. This is undefined behaviour
You almost certainly don't want a void pointer to an array of pointer-to-pointer-to-void. If you really want an array of pointer-to-integer, then you want int** array = new int*[2];. Or probably just int *array[2]; unless you really need the array on the heap.
j is the probably in the same place each time through the loop - it will likely be allocated in the same place on the stack - so &j is the same address each time. In any case, j will go out of scope when the loop's finished, and the address(es) will be invalid.
What are you actually trying to do? There may well be a better way.
if you simply do
int *array[10];
your array variable can decay to a pointer to the first element of the list, you can reference the i-th integer pointer just by doing:
int *myPtr = *(array + i);
which is in fact just another way to write the more common form:
int *myPtr = array[i];
void* is not the same as int*. void* represent a void pointer which is a pointer to a specific memory area without any additional interpretation or assuption about the data you are referencing to
There are some problems:
1) void *array = new void*[2]; is wrong because you want an array of pointers: void *array[2];
2)for (int i = 0; i < 3; i++) { : is wrong because your array is from 0 to 1;
3)int j = i + 1; array[i] = *j; j is an automatic variable, and the content is destroyed at each iteration. This is why you got always the same address. And also, to take the address of a variable you need to use &

Unitialized local variable and help correcting

I am learning about pointers and the new operator in class.
In my readArray function I am to read in a size. Use the size to dynamically create an integer array. Then assign the array to a pointer, fill it, and return the size and array.
I believe I've gotten that part corrected and fixed but when I try to sort the array, i get the error "uninitialized local variable temp used."
The problem is though I get that error when I am trying to intialize it.
Any help appreciated thank you. Seeing my errors is very helpful for me.
#include <iostream>
using namespace std;
int* readArray(int&);
void sortArray(int *, const int * );
int main ()
{
int size = 0;
int *arrPTR = readArray(size);
const int *sizePTR = &size;
sortArray(arrPTR, sizePTR);
cout<<arrPTR[1]<<arrPTR[2]<<arrPTR[3]<<arrPTR[4];
system("pause");
return 0;
}
int* readArray(int &size)
{
cout<<"Enter a number for size of array.\n";
cin>>size;
int *arrPTR = new int[size];
for(int count = 0; count < (size-1); count++)
{
cout<<"Enter positive numbers to completely fill the array.\n";
cin>>*(arrPTR+count);
}
return arrPTR;
}
void sortArray(int *arrPTR, const int *sizePTR)
{
int *temp;
bool *swap;
do
{
swap = false;
for(int count = 0; count < (*sizePTR - 1); count++)
{
if(arrPTR[count] > arrPTR[count+1])
{
*temp = arrPTR[count];
arrPTR[count] = arrPTR[count+1];
arrPTR[count+1] = *temp;
*swap = true;
}
}
}while (swap);
}
You make temp an int pointer (uninitiialized), and then set the thing it points at (anything/nothing) to arrPTR[ccount]. Since you are using temp only to swap, it should be the same type as those being swapped, in this case: an int.
If it absolutely must be a pointer (there is no good reason for this, it's slow, confusing, adds potential for errors, and adds potential for memory leaks):
int *temp = new int; //make an int for the pointer to point at
bool *swap = new bool; //make an bool for the pointer to point at
do
{
//your code
}while (swap);
delete temp;
delete swap;
You declared temp as a pointer. You need to allocate it on the heap before dereferencing and assigning to it later. However perhaps a variable on the stack would be preferable?
FYI: You should be aware of the memory leak in readArray as well which is leaving callers responsible for calling delete []
Edit: I hope this will help clear up some of the other problems.
#include <iostream>
int* readArray(int&);
void sortArray(int*, int);
int main ()
{
int size(0); // use stack when possible
int *arrPTR = readArray(size);
sortArray(arrPTR, size);
// arrays are zero based index so loop from 0 to size
for (int index(0); index < size; ++index)
std::cout << arrPTR[index];
delete [] arrPTR; // remember to delete array or we have a memory leak!
// note: because we did new[] for an array we match it with delete[]
// if we just did new we would match it with delete
system("pause");
return 0;
}
int* readArray(int& size)
{
std::cout << "Enter a number for size of array.\n";
std::cin >> size;
int *arrPTR = new int[size]; // all news must be deleted!
// prefer pre-increment to post-increment where you can
for(int count(0); count < size; ++count)
{
std::cout << "Enter positive numbers to completely fill the array.\n";
std::cin >> arrPTR[count];
}
return arrPTR;
}
// passing size by value is fine (it may be smaller than pointer on some architectures)
void sortArray(int *arrPTR, int size)
{
// you may want to check if size >= 2 for sanity
// we do the two loops to avoid going out of bounds of array on last iteration
for(int i(0); i < size-1; ++i) // the first to compare (all except last)
{
for(int j(i+1); j < size; ++j) // the second to compare (all except first)
{
// do comparison
if (arrPTR[i] > arrPTR[j]) // from smallest to biggest (use < to go from biggest to smallest)
{
// swap if needed
int temp(arrPTR[i]); // put this on stack
arrPTR[i] = arrPTR[j];
arrPTR[j] = temp;
}
}
}
}
temp is a "pointer to int, which you're not initializing. When you say *temp = ... you're actually assigning to whatever temp happens to be pointing, but since you haven't told it what to point to, it can write pretty much anywhere in the address space of your program.
Because of the way you're using them, it seems that temp and swap shouldn't be pointers at all, just a plain int and bool.
You didn't initialize the temp pointer do when you dereference it you are writing to a random part of memory. Temp doesn't need to be a pointer, it can just be an int. Just replace EVERY instance of *temp with temp.