using delete[] in main when new int [] was declared in a function - c++

My first job is this:
"The first function, readNumbers, is to read a set of 10 numbers from std::cin and use them to initialise a dynamically allocated array of int of length 10 (dynamic allocation is on the heap). The function must return a pointer to the array. You may assume that the input will be 10 integer values and nothing else."
which is fine, however i need to then:
"The main function for this problem must call your readNumbers function, then pass the new array to your printNumbers function and finally delete the array."
However i am unsure of how to handle the delete in main, when the new int [] has been declared in a function. here is the relevant parts of my code.
int *readNumbers(){
int * numbers;
numbers = new int [10];
for (int i = 0; i < 10; i++){
int userinput;
cin >> userinput;
*(numbers+i) = userinput;
}
return numbers;
}
and
int main(){
printNumbers(readNumbers(),10);
delete[] numbers;
}
obviously the delete[] request in main is a syntax error, i am unsure of the solution.

You need to assign the result of readNumbers() to a variable, then you can delete it.
int main() {
int *numbers = readNumbers();
printNumbers(numbers, 10);
delete[] numbers;
return 0;
}

Related

C++ question including pointer, array and function

So I have two programs here,
the first one is using dynamic allocation
and the second one is using fixed sized array.
Now the question is, by using dynamic allocation, the program runs fine AND outputs are correctly printed as expected.
However, when using fixed sized array (the second program), the program runs without errors BUT the outputs are not what I wanted.
The programs are almost same except how the arrays are created..but still both the arrays are same so shouldn't outputs be the same?
What are the reasons?? Please help me understand..
First Program Example:
input1 output1
1 1
2 2
3 3
4 4
5 5
Second Program Example:
input1 output1
1 1
2 5
3 2058618480
4 32766
5 5
// Using Dynamic Allocation
#include <iostream>
int *readNumbers(int n) {
int *a ;
a = new int[n];
for (int i=0; i<n; i++) {
std::cout << "enter for a["<<i<<"]: ";
std::cin >> a[i];
}
int *ptr;
ptr= &a[0];
return ptr;
}
void printNumbers(int *numbers,int length){
for (int i=0; i<length; i++) {
std::cout << *(numbers+i) << "\n";
}
}
int main(){
int n;
std::cout << "enter for n: " ;
std::cin >> n;
int *ptr;
ptr = readNumbers(n);
printNumbers(ptr,n);
delete [] ptr;
ptr = NULL;
return 0;
}
And another one is
// Using fixed size array
#include <iostream>
int *readNumbers(int n) {
int a[5]={};
for (int i=0; i<5; i++) {
std::cout << "enter for a["<<i<<"]: ";
std::cin >> a[i];
}
int *ptr;
ptr = &a[0];
return ptr;
}
void printNumbers(int *numbers,int length){
for (int i=0; i<length; i++) {
std::cout << *(numbers+i) << "\n";
}
}
int main(){
int *ptr;
ptr = readNumbers(5);
printNumbers(ptr,5);
return 0;
}
In your second piece of code your array is allocated on the stack inside the readNumbers function. Then you return a pointer to that stack memory to the calling function. This memory is no longer valid when printNumbers is run. It has likely been overwritten by locals in printNumbers.
Allocate the array in main and then the second example should also work.
I feel in first case, when you call new operator to allocate memory for storing multiple int values, heap memory is allocated. Now this memory is available when you pass it around functions and this memory is valid till programming is running until someone calls delete operator. So you could pass this pointer from readNumbers, main and printNumber and it is valid.
For second case you created array of int as local variable in function, so it is created in stack. Scope of the local variable is only till the function is running. In your example readNumbers created array and once the function is over the stack is cleared. That is all the local variables created in function are no longer valid.
Hence when you use this memory location in other functions like main and printNumbers it will give undefined behaviour. Sometime the result will be expected sometimes invalid result. So you need to be careful what are you passing or returning from one function to another.
If you still want to get expected result in second case, declare arrray as static.
Hope this helps.

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);
}

getting multiple errors for this code within the for loop and for the variable value;

used the variable value as a size of an array but it will not let me.
int main () {
double a,b,N,increment,value;
value=0;
cout<< "enter values for (a,b,N)";
cin>>a;
cin>>b;
cin>>N;
increment= (b-a)/(N-1);
for (int i =0;i<=b;i+=increment){
value = value+i;
}
double sivalues[value];
for (int x=a;i<=b;i+=increment){
sivalues[a]=si(x);
cout<<"si("<<x<<") = "<< sivalues[a];
}
The item placed inside the [] when creating an array must be constant. This does not apply however when you create arrays on the heap.
int mySize = 50;
int myArray[mySize]; // error: mySize must be const
int* myHeapArray = new int[mySize]; // all good! (just don't forget to free the memory)

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.

How do I return a dynamically allocated pointer array from a function?

I am now starting Dynamic Memory Allocation in class and have a ok understanding of it but can't completely use it properly. I feel like I may not be so great with pointers either :p
My instructor gave instructions to create a function named readArray that will prompt the user for a number to use as a size to dynamically create a integer array of that size. I am then to assign the new array to a pointer. I then am supposed to prompt the user to fill the array. I then am supposed to return both the newly created array and the size.
I can not figure out how to return the array though, and I thought when dynamically allocating memory you were supposed to delete the allocation after using it to prevent leaks.
The array and size must be returned to main so I can pass it to other functions such as a sorting function.
I would greatly appreciate any help I can get as my thought process with this keeps going in the wrong direction.
#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;
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;
}
You would not need to do that if you use std::vector<int> which is far superior choice.
Use it:
std::vector<int> readArray()
{
int size = 0;
cout<<"Enter a number for size of array.\n";
cin >> size;
std::vector<int> v(size);
cout<<"Enter "<< size <<" positive numbers to completely fill the array : ";
for(int i = 0; i < size; i++)
{
cin>> v[i];
}
return v;
}
To return an array: declare readArray() as int* readArray() [return an int* instead of an int], and return arrPTR instead of size. This way, you return the dynamically allocated array which arrPTR points to.
Regarding the delete: When you are done using the array, you should indeed delete it. In your example, do it before return 0 in your main() function.
Make sure that since you allocated memory with new[], you should also free it with delete[], otherwise - your program will have a memory leak.
Like amit says, you should probably return the array instead of size. But since you still need the size, change readArray like so:
///return array (must be deleted after)
///and pass size by reference so it can be changed by the function
int* readArray(int &size);
and call it like this:
int size = 0;
int *arrPTR = readArray(size);
///....Do stuff here with arrPTR
delete arrPTR[];
After update:
int* readArray(int size); ///input only! need the & in the declaration to match
///the function body!
Is wrong, since you have your actual definition with the int &size.
You also don't declare arrPTR in readArray, just assign it.