Returning a Pointer from a function c++ - c++

When I try to compile in C++ it says that there is an undefined reference to sort_Array(int *, int). I have been messing with this for about an hour and I can't figure out why I am getting this error. I thought it was telling me to use a pointer. I have to use the prototype exactly as it is written for the assignment so i can't change the array to a pointer or pass it by reference like I thought it was telling me to. I also have to get the size of the array from the user. Could this be a situation where I need to dynamically allocate the array. It crossed my mind, but I am not sure.
This is the prototype
int *sort_Array(int [], int);
This is how I am trying to use it
int size;
int initial_Array[size];
cout << "What is the size of your array?" << endl;
cin >> size;
cin.ignore();
sort_Array(initial_Array, size);
This is the actual function
int *sort_array(int unsorted_Array[], int size)
{
int *sorted_Array, i;
sorted_Array = new int[size];
//Function for sorting the array.
selection_Sort(unsorted_Array, size);
//Copies the newly sorted unsorted array variable to the sorted array varible.
for(i=0; i<size; i++)
{
unsorted_Array[i] = sorted_Array[i];
}
return sorted_Array;
}

You define intial_Array with an uninitialised size:
int size;
int initial_Array[size];
Which is UB.
But your error comes from calling sort_Array when you've defined sort_array

Related

C++ printing array results

I was able to fix some of the errors. Now I am just getting 3.
1. control reaches end of non-void function at } before the
void displayIntegerArray(int *arrayPtr,int arraySize) function.
2. expected expression at delete[];.
3. expected expression at return 0;.
#include <iostream>
#include <iomanip>
using namespace std;
// Function prototypes
void populateIntegerArray(int *arrayPtr, int arraySize);
void displayIntegerArray(int *arrayPtr, int arraySize);
void findMaximumInteger(int *arrayPtr, int arraySize);
//method to populate array
void populateIntegerArray(int *arrayPtr,int arraySize)
{
for(int i=0;i<arraySize;i++)
{
cout<<"Enter value for array element:"<<i<<":";
cin>>arrayPtr[i]; //reading value
}
}
void findMaximumInteger(int *arrayPtr,int arraySize)
{
int maximum = arrayPtr[0];
{
for(int i=0;i<arraySize;i++)
{
if(maximum<arrayPtr[i])maximum=arrayPtr[i];
}
cout<<"Maximum integer in array is: "<<maximum<<endl;
}
}
void displayIntegerArray(int *arrayPtr,int arraySize)
{
for(int i=0;i<arraySize;i++)
{
cout<<&arrayPtr[i]<<": arrayPtr["<<i<<"] = "<<setw(15)<<arrayPtr[i]<<endl;
}
}
int main()
{
int arraySize;
// Read array size
cout<<"Enter desired array size:";
cin>>arraySize;
// Print array
cout<<"arrayPtr = "<<arraySize<<endl;
populateIntegerArray( arrayPtr, arraySize);
displayIntegerArray(arrayPtr, arraySize);
findMaximumInteger( arrayPtr, arraySize);
cout<<"DELETING array at arrayPtr = "<<arrayPtr<<endl;
delete[];
return 0;
}
In main function:
There is undeclared variable; arrayPtr.
So you have to declare it and allocate memory for it dynamically.
int* arrPtr = new int[arraySize];
You also have to provide the delete [] operator the arrayPtr to free the memory allocated.
Finally main function will be like that:
int main()
{
int arraySize;
// Read array size
cout<<"Enter desired array size:";
cin>>arraySize;
int *arrayPtr=new int[arraySize];
// Print array
cout<<"arrayPtr = "<<arraySize<<endl;
populateIntegerArray( arrayPtr, arraySize);
displayIntegerArray(arrayPtr, arraySize);
findMaximumInteger( arrayPtr, arraySize);
cout<<"DELETING array at arrayPtr = "<<arrayPtr<<endl;
delete[] arrayPtr;
return 0;
}
So there are a couple of things that ain't quite right with your program my dude, but they mainly stem from you not creating a arrayPtr in main. If you don't create something to point to a chunk of memory then your program wont know where the array is.
https://www.cplusplus.com/doc/tutorial/pointers/
The next problem is that, because you never created the pointer to the memory, you also forgot to create the space for the memory. If the array was the same size every time your program ran and was reasonably small then you could just allocate the space on the stack. However you don't so you need to allocate the memory dynamically. This means that you need to ask your operating system for the memory and get back its location. This can be done with the new[] operator. Then when you are done using the memory you tell the program to de-allocate it with the delete[] operator. (If you don't then memory will keep being marked as used despite your program ending. This is called a memory leak.)
https://www.cplusplus.com/doc/tutorial/dynamic/
Next you aren't actually displaying the location of the array. You want to print the new arrayPtr variable to see the location.
Lastly your post is a bit hard to work with. The formatting is a bit inconstant and that makes it significantly harder to read. Luckily your program was simple enough that it isn't too time consuming to read through and figure out what is going wrong. However, as your programs get more complex and larger, many people won't be willing to look through your whole program and find your bugs for you. Try to narrow down where you think the error is coming from and post: some context, the relevant chunk of code, and the exact error messages.

C++ how to pass string array in function and assign to a variable?

I got this error while coding a simple function. This is my function specification.
string studentName;
string courseTaken[3];
void setStudent(string, string[]);
void Student::setStudent(string n, string a[])
{
studentName= n;
courseTaken = a;
}
This is the error I have gotten:
incompatible types in assignment of string* to string [3] on this line courseTaken = a;
In my code, I never declared any pointer or char.
I don't quite understand what is going wrong here.
You can not assign array of strings string a[] to array courseTaken using = operator. The expression string a[] is equivalent to std::string*. That is why you get the compiler error.
This may be what you wanted:
#include <iostream>
using namespace std;
class Student
{
public:
string studentName;
string courseTaken[3];
void setStudent(string n, string a[]);
};
void setStudent(string n, string a[]);
void Student::setStudent(string n, string a[])
{
studentName = n;
for(int i=0; i < sizeof(courseTaken)/sizeof(courseTaken[0]); i++)
courseTaken[i] = a[i];
}
int main()
{
Student student;
string courses[3] = {"Cobol","C++","Fortran"};
student.setStudent("Eva", courses);
for (int i = 0; i < 3; i++){
cout << student.courseTaken[i] << endl;
}
return 0;
}
Output:
Cobol
C++
Fortran
It seems you don't understand array decay mechanism of C-format arrays.
For many context, an array name will be explained as a pointer to the first element of the array. And this pointer is a prvalue which just like this pointer, you can NOT assign to it.
the "modern Cpp way"(C++11) is to use std::array, which overloaded the =operator and stores the size of the array so that it won't be decayed while passing to a function.
The second way is to pass the reference, with a template you can ensure the array's size, then use std::memcpy. And you can add a parameter stores the array's size, and then you can use memcpy too.
I hope you use the first way, don't forget -std=c++11
This is because you are passing an array to a variable that's why this error occurs. To solve this problem you may use pointer in argument to solve this problem. Change your function to this.
void Student::setStudent(string n, string* a)
{
studentName= n;
courseTaken = a;
}

Array initialization functions

I was playing around with C++ and I stumbled upon this problem. I'm trying to initialize an array pointer on the heap, and it works inside the initialize(), where it outputs 69, but in the main(), it crashes with the error EXC_BAD_ACCESS.
#include <iostream>
void initialize(int* array, int size) {
array = new int[size];
// Testing
array[2] = 69;
std::cout << array[2] << std::endl; // Works fine
}
int main() {
int size = 3;
int* array;
// Initializing
initialize(array, size);
// Testing
std::cout << array[2] << std::endl; // Crash, EXC_BAD_ACCESS
// Cleanup
delete[] array;
array = nullptr;
return EXIT_SUCCESS;
}
Please help me understand the problem with this.
Yes, I know I should use std::vector but I want to understand why this doesn't work :)
When you pass array to the function, a copy of that pointer is made. When you assign new int[size]; to array, you assign it actually to the argument, which is the copy I was talking about. To really modify the array defined in main, use references. Change the definition of the function to
void initialize(int*& array, int size)
or return the pointer like1
int* initialize(int size)
and try it again.
I recommend the second method due to its higher expressiveness: something like
initialize(array, 3);
does not make clear if array is modified or not. OTOH,
int* array = initialize(3);
does.
1 as noted by #Jack in the comments to this answer
The reason why the program fails is because you want the memory to be allocated outside the initialize function and the function to operate on that memory.
Simply remove the new statement from your function so that it looks like this...
void initialize(int* array, int size) {
for (int i = 0; i < size; i++) {
cout << array[i] << " ";
}
}
... then, do your allocation in main and just before the function call...
int size = 3;
int* array = new int [size];
initialize(array, size);
Pass the address of the pointer to avoid the error message

C++ Passing Static Array and Dynamic Array By Reference

To fully understand how pointers, values, and references work, I am making a basic C++ program that attempts to tamper with some static and dynamic arrays and understand exactly how they should be passed in.
First I generate a static array of 3 elements. I then pass it into a function that modifies all elements. I then pass it into another function with a slightly different signature, but can also alter the array's values.
Next I generate a dynamically sized array, pass it into a function by reference so that all of the values in this dynamically sized array can be altered.
The code is as follows:
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
void changeIndexStaticArrayMethod1(int* stat);
void changeIndexStaticArrayMethod2(int (&stat)[3]);
void changeIndexDynamicArrayMethod1(int* dyn, int size);
int main() {
const int MAX = 3;
int arr[MAX] = { 1,2,3 };
changeIndexStaticArrayMethod1(arr);
cout << arr[0] << endl;
cout << arr[1] << endl;
cout << arr[2] << endl;
cout << endl;
changeIndexStaticArrayMethod2(arr);
cout << arr[0] << endl;
cout << arr[1] << endl;
cout << arr[2] << endl;
int SIZE;
cout << "Please choose a size for the array" << endl;
cin >> SIZE;
int *ne = new int[SIZE];
//Build array
for (int i = 0; i < SIZE; i++) {
ne[i] = i;
}
changeIndexDynamicArrayMethod1(ne, SIZE);
for (int i = 0; i < SIZE; i++) {
cout << "ne[" << i << "] = " << ne[i] << endl;
}
//To hang program
cin >> SIZE;
delete[] arr;
delete[] ne;
return 0;
}
void changeIndexStaticArrayMethod1(int* stat) {
stat[0] = 10;
stat[1] = 20;
stat[2] = 30;
}
void changeIndexStaticArrayMethod2(int (&stat)[3]) {
stat[0] = 40;
stat[1] = 50;
stat[2] = 60;
}
void changeIndexDynamicArrayMethod1(int* dyn, int size) {
for (int i = 0; i < size; i++) {
dyn[i] = i * 10;
}
}
All of the above code works how I want it to, I just have a few questions as to why (some of the methods of passing arrays by reference I have found on other SO questions).
In the changeIndexStaticArrayMethod1() and changeIndexDynamicArrayMethod1() functions, why are we able to use the dereference * operator for our array as reference? My knee jerk reaction is seeing that as practically passing the array in by values since it is the dereference operator. I know that with arrays, it is much different than using variables, but also, why will the following not work for single int variables:
void changeStaticNumber(int* num){
num = 100;
}
Obviously the above will work if we use &num and not int* num, and obviously I don't fully understand the relationship between pointers and arrays, but I cannot figure out why when we pass an array by reference, int* staticArray is ok.
Any explanation for these problems I am having would be much appreciated. Thanks.
why are we able to use the dereference * operator for our array as reference?
The * in C means many things. It can mean the unary indirection ("contents of") operator, it can mean the binary multiplication operator and it can mean a pointer declaration. The int* stat is a pointer declaration.
Since you aren't using the * to dereference the contents of the pointer inside that function, I'm not quite sure what you are asking.
When you take the array name of your array in main(), it "decays" into a pointer to the first element. So what those function do, is to take a pointer by value. If you dereference the pointer by typing *stat = something; you access the actual array in main.
Should you do something weird like changing the pointer itself, for example stat++;, then it will not affect the address used in main. You passed the pointer itself by value, so the pointer is a local copy.
My knee jerk reaction is seeing that as practically passing the array in by values since it is the dereference operator.
You can't really pass arrays by value in C or C++, without resorting to dirty tricks (storing them inside structs or classes). For example, had your function been written as void changeIndexStaticArrayMethod1(int stat[3]) it would still give you a pointer to the first element. It will not pass an array by value, as the syntax might trick you into believing.
why will the following not work for single int variables:
void changeStaticNumber(int* num){ num = 100; }
Because num is the pointer itself, not its contents. In order to write code like that, you could pass the variable by reference int& num. Behind the lines this is really the same thing as passing a pointer, just with simplified syntax.
To understand the relation between pointers and arrays better, start by reading this whole chapter: http://c-faq.com/aryptr/index.html (C and C++ are identical when it comes to pointers).
Let me see if I can take a stab at this.
Pointers are simply address holders. Once you do int * ptr = myarray; --- what you are in tern doing is storing the address of the pointer my array into ptr --- array names are actually pointers to the first memory location in the array. You can use pointer arithmetic to get at everything else for example myarray +1 will point you to the next location or myarray[1].
Passing by value is not very useful when you need to modify your array. Passing in by reference is essentially making a pointer to the array and passing that. Since arrays like vectors are contiguous blocks of memory you can index through them rather easily.
As far as your example goes void changeStaticNumber(int* num){ num = 100; } will not work because what you are attempting to do is store 100 into the pointer's address. If you deference num and make it void changeStaticNumber(int* num){ *num = 100; } it will work because you are actually going one step further and accessing the data that num is pointing to. When you use &num it is essentially the same thing - & just gives you the address of something.
For example if you want to point a pointer to an int what you would do is
int num = 5;
int *ptr = &num;
at this point in time ptr has the same address in num. To print out the data in num or that ptr is pointing to you need to dereference or go one step further as I like to tell myself and dereference to so cout << *ptr;
In both changeIndexStaticArrayMethod1 and changeIndexDynamicArrayMethod1 you are not passing an array there is no pass by reference (which only happens if the parameter type is a reference type -- i.e. with &). The parameter has type int * (pointer to int). You are passing a pointer to int by value. There is no "dereference operator" in either function.
ne is already an int *, so passing it is nothing special. arr is an int [3], an array, not a pointer. In C, when an array-of-T is used in a context that expects a pointer-to-T, it is implicitly converted (without you needing to do anything) to a pointer to its first element. So when you do, changeIndexStaticArrayMethod1(arr), the compiler gets a pointer to the first element of arr, and passes that to the function.
The [] operator works on pointers. a[i] is always guaranteed to be the same as *(a + i). Inside both the changeIndexStaticArrayMethod1 and changeIndexDynamicArrayMethod1 functions, [] is used to access subsequent elements using a pointer to the first element.

How to allocate memory dynamically using pointers?

I have the following task:
Creat a program that will transform array A to array B in the followin order:
http://gyazo.com/29e434ebdc1e235fe0fc97c26ae9fe9c
The size of A is entered by user, as well the elements. Print the new elements of B. "Use pointers"
Examples: If I input 1234567, the program will output 8888888.
Here's my code:
#include <iostream>
using namespace std;
int main()
{
int N;
cout << "Enter the size of array" << endl;
cin >> N;
int A[N], B[N];
cout << "Enter the elements of the array" << endl;
for(int i = 0; i < N; i++){
cin >> A[i];
}
for(int i = 0; i < N; i++){
B[i] = A[i] + A[N-i-1];
}
for(int i = 0; i < N; i++){
cout << B[i] << " ";
}
return 0;
}
There is only one problem I have, it says to "use pointers" but I don't know where shall I use them and they must be used... thanks in advance.
int A[N], B[N];
This code is non-standard (when N is a variable). Your compiler allows that, but if you try to compile this code in other one, it probably won't work.
Using pointers in this case means, that you should allocate memory for the arrays dynamically, eg.
int * A, * B;
A = new int[N];
B = new int[N];
This code is valid in terms of C++ standard.
Remember though, that you will have to free allocated memory manually after you don't need it anymore:
delete[] A;
delete[] B;
This should work with the rest of your code left unchanged, since [] operator works for pointers as well.
And finally, if you really are writing a C++ program, you surely should be using std::vector instead of C-style arrays...
Edit: (in response to comment)
If you declare a variable in the following way:
int * A;
And then write:
cin >> *(A + i);
It means:
Read data from user and parse it;
Go i "steps" starting from address A (it actually "walks" i * sizeof(*A) bytes from A).
Put the data read from the user to memory pointed to by place evaluated in step 2.
But when you declare:
int (*A)[N];
The A becames pointer to the array of N elements. Since array is convertible to a pointer to its first element, you may think of that previous line (for the sake of explanation) as
int ** A;
In such case compiler tries to do the same as I described earlier. But now it walks i pointers starting from A, not *int*s. Then it dereferences that pointer getting an int * and attempts to put there data written by user. But >> operator of cin is not able to translate text to a pointer and that's why compiler complains.
Foot note
While you're learning using pointers, you may think of <something> variable[] as being equal to <something> * variable pointing to the first element of that array. This is a lie (because array is not a pointer, but it's convertible to a pointer to its first element), but helps understanding what arrays do have in common with pointers. That's why you can think of
int (* A)[];
As a
int ** A;
Well, this
cin >> N;
int A[N], B[N];
is not valid ANSI C++. You cannot declare arrays with variable indices. So you need a way to declare variable length arrays, and one way is to use pointers and dynamically allocated memory using new[] (and then delete[]).
The other, preferable method would be to use a container such as std::vector.