C++ Write Stack Value to Array-Pointer / (Call by Ref-Function) - c++

I'm currently learning C++ and wrote an Array Reverse Function for learning purposes only.
Everything works fine. But if i want to write back my value from my stack into my array.. it fails.
#include "iostream"
#include <stack>
using namespace std;
void reverseArray(int *a, int s) {
stack<int> stack;
register int i;
for (i = 0; i < s; i++) { // iterates from 0 to 5
stack.push(*a);
a++; // pointer adress + 4 byte
}
for (i = 0; i < s; i++) { // iterates from 0 to 5
a = &stack.top(); // this fails!!
printf("%i\n", *a); // Here ist the right output
stack.pop();
a++; // pointer adress + 4 byte
}
}
int main() {
const int SIZE = 5;
int array[SIZE] = {1, 2, 3, 4, 5};
reverseArray(&array[0], SIZE);
printf("This should be 5: %i\n", array[0]);
return 0;
}
This creates following output:
5
4
3
2
1
This should be 5: 1

With the statement
a = &stack.top();
you have two problems:
You assign to a local variable. That assignment will not outlive the life-time of the variable, which is until the function returns.
You make the variable point to data that will no longer exist once you pop the element.
The solution to both of these issues is to save the value of a into a temporary variable that you use for the first loop. Then you can use a in the second loop much like you do in the first loop currently, and assign to its dereferenced value (like e.g. *a++ = stack.top()).
On an unrelated note, the register keyword has been deprecated since C++11 and will be removed in C++17. It will most certainly not do anything.

I just solved the problem.
*arrayin this case is always pointing to the first item in array -> array[0]
I don't need array++, because i calculate it with *(array + i)
void reverse(int *array, const int s) {
stack<int> stack1;
for (int i = 0; i < s; i++) {
stack1.push(*(array + i));
}
for (int i = 0; i < s; i++) {
*(array + i) = stack1.top();
stack1.pop();
}
}

Related

return a dynamically allocated array of the same length but with the elements in the reverse order

Write a function, reverseArray, that when passed an int array of length greater than 0 will return a dynamically allocated array of the same length but with the elements in the reverse order. For example, if passed the array, {1,2,3,4,5,6,7,8,9,0} the function would return the array {0,9,8,7,6,5,4,3,2,1}.
Below is my code, but there is a bug in it.
This is my output.
1
2
3
4
5
6
4113
6
5
4
3
2
1
0x7fffe697ceb0
The 4113 and address are provided by the compiler.
#include <iostream>
using namespace std;
int * readNumbers() {
int * a = new int[6];
for (int i = 0; i < 6; i++) {
int x;
cin >> x;
a[i] = x;
}
// a++;
return a;
delete[] a;
}
int *reverseArray(int *numbers1,int length) {
for (int i = length; i >=0; i--) {
cout << numbers1[i] << endl;
}
return numbers1;
delete [] numbers1;
}
int main() {
int *arr1 = readNumbers();
cout << reverseArray(arr1,6) << endl;
return 0;
}
I think there may have been an issue with your wording. Assuming you want your function just to print the reverse of a passed array, you're off to a good start.
One issue is what was said in the comments: your for loop is indexing past your array. When you type int * a = new int[6]; you are creating a pointer 'a' which points to a location in memory. Since you chose size 6, the appropriate amount of memory is allocated. If you happen to index outside of that range, you will end up pointing to a random spot in memory, not allocated for your array. Hence why you are getting a weird number '4113'.
A fix for this could be:
int i = length changed to int i = length-1
Another issue is that your function returns an integer pointer, and you are trying to cout this pointer. As another commenter said, you have to think about what this does. If you try this code:
#include <iostream>
using namespace std;
int main() {
int arr[] = {1, 2, 3};
cout << arr << endl;
return 0;
}
your output would be something like 0xff09ba. This represents the location of the start of the array in memory. If you change arr to (arr + 1) you will get the location of the second index of the array.
So when you type cout << reverseArray(arr1,6) << endl; you are really just printing out the location of numbers1 in memory. This is why you are getting '0x7fffe697ceb0' in your output. To fix this, simply make your function
void reverseArray(int *numbers1,int length) {
for (int i = length; i >=0; i--) {
cout << numbers1[i] << endl;
}
}
and change your main to:
int main() {
int *arr1 = readNumbers();
reverseArray(arr1,6);
return 0;
}
Now, if you actually want to return this array, you would need to create a new array which holds the reverse numbers and then return that. An example of a function that does that is:
int* reverseArray(int *numbers1,int length) {
int j = 0;
int *numbers2 = new int[length];
for (int i = length-1; i >=0; i--) {
numbers2[j] = numbers1[i];
j++;
}
return numbers2;
}
There are probably better ways to do this, but this is just one solution. Regardless, you should always be careful when allocating memory yourself.

c++ main function use two times of function

Write a function, equalsArray that when passed two int arrays of the same length that is greater than 0 will return true if every number in the first array is equal to the number at the same index in the second array. If the length of the arrays is less than 1 the function must return false. For example, comparing the two arrays, {1,2,3,4,5} and {1,2,3,4,5} would return true but the two arrays {3,7} and {3,6} would return false.
You should start by copying the function-1-1.cpp file and name it function-3-1.cpp. Then add the function equalsArray to the new file.
The main function for this problem must call your readNumbers function twice, then pass both new arrays to your equalsArray function, display the result as true or false and finally delete the array. The main function in the file main-3-1.cpp.
The signature for your new function is:
bool equalsArray(int *numbers1,int *numbers2,int length) ;
This is my code, and i try to use the int* readNumber two times.
#include <iostream>
using namespace std;
int* readNumbers()
{
int* a = new int[10];
for (int i = 1; i < 11; i++) {
int x;
cin >> x;
a[i] = x;
}
a++;
return a;
// delete[] a;
}
bool equalsArray(int* numbers1, int* numbers2, int length)
{
if (length >= 1) {
for (int i = 0; i < length; i++) {
if (numbers1[i] == numbers2[i]) {
}
else {
return false;
}
}
return true;
}
// delete[] numbers1;
// delete[] numbers2;
int main()
{
int* arr1 = readNumbers();
int* arr2 = readNumbers();
equalsArray(arr1, arr2, 10);
return 0;
}
There there is an error,control reaches end of non-void function.
How to improve my code?
Thank you all.
Expect result:
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
True(1)
OK, first I will show you your code, with comments where the errors are.
Then I will show you a fixed version. And, at the end, a little bit more robust C++ soultion.
I know that you learn in school all this nasty stuff with pointers, decayed pointers for arrays, C-style arrays,pointers for owned memory, new and delete.
That is basically bad. It should never be used in C++.
Anyway. Teachers still think like that. What a pity . . .
OK. You code with comments:
#include <iostream>
using namespace std; // Should not be used
int* readNumbers()
{
int* a = new int[10]; // Do not use C-style arrays, pointer for owned memory, new and delete
for (int i = 1; i < 11; i++) { // Will lead to out of bound error
int x; // Why using additional variables?
cin >> x;
a[i] = x;
}
a++; // Wrong
return a;
// delete[] a; // Not here
}
bool equalsArray(int* numbers1, int* numbers2, int length)
{
if (length >= 1) {
for (int i = 0; i < length; i++) {
if (numbers1[i] == numbers2[i]) {
}
else {
return false;
}
}
return true;
}
// Here nothing will be returned
} // Closing bracket misding
// delete[] numbers1; // Not here
// delete[] numbers2; // Not here
int main()
{
int* arr1 = readNumbers();
int* arr2 = readNumbers();
equalsArray(arr1, arr2, 10);
return 0; // No output
} // No Release of memory
Next, your fixed code
#include <iostream>
using namespace std;
// Function to read a given numbers of values and returns them in a dynaimcally allocated array
int* readArrayOfNumbers(int numberOfValuesToRead) {
// Allocate a new array for the given amount of integers
int* dynamicArrayOfIntegers = new int[numberOfValuesToRead];
// Read all values in a loop from user via std::cin
for (int index = 0; index < numberOfValuesToRead; ++index) {
cin >> dynamicArrayOfIntegers[index];
}
return dynamicArrayOfIntegers;
}
// Compare 2 arrays with same size
bool equalsArray(int* numbers1, int* numbers2, int length) {
// We assume in the beginning that the arrays will be equal
bool result = true;
// We will only compare arrays, if they contain data
if (length >= 1) {
// Now compare arrays element by element
for (int i = 0; i < length; i++) {
if (numbers1[i] != numbers2[i]) {
// If not equal then set result to false and stop loop
result = false;
break;
}
}
}
else {
// No data in array. Consider as not equal
result = false;
}
return result;
}
int main()
{
// Define size of arrays
const int sizeOfArray = 10;
// Get 2 arrays in dynamically allocated arrays
int* array1 = readArrayOfNumbers(sizeOfArray);
int* array2 = readArrayOfNumbers(sizeOfArray);
// Compare both arrays
const bool arraysAreEqual = equalsArray(array1, array2, sizeOfArray);
// Show result
if (arraysAreEqual)
std::cout << "\nTrue(1)\n";
else
std::cout << "\nFalse(0)\n";
// Release memory
delete[] array1;
delete[] array2;
}
And finally, the C++ solution
#include <iostream>
#include <iomanip>
#include <array>
constexpr size_t NumberOfElements = 10u;
using MyType = int;
using MyArray = std::array<MyType, NumberOfElements>;
int main() {
// Define arrays
MyArray myArray1{};
MyArray myArray2{};
// Read values
for (size_t i{}; (i < NumberOfElements) and (std::cin >> myArray1[i]); ++i)
;
for (size_t i{}; (i < NumberOfElements) and (std::cin >> myArray2[i]); ++i)
;
// If all numbers could be read . . .
if (std::cin) {
// Show result of comparison
std::cout << '\n' << std::boolalpha << (myArray1 == myArray2) << '(' << (myArray1 == myArray2) * 1 << ")\n";
}
else std::cerr << "\n*** Error. Invalid input data\n";
}

How do you return an array that has multiple values from a function? C++

I am trying to return a certain array from a function that when called, assigns value to the array
The function should go something like this:
int arr[10];
int values[10] = {1,2,3,4,5,6,7,8,9};
for (int i =0; i<10; i++)
{
arr[i] = values[i];
}
How do I translate this code into a function?
using namespace std;
As far I know, you shouldn't be looking to return an array from a function... like, ever.
What I would do instead is pass the names of the arrays to the function and have it process the contents in whatever way you need it to. In your case, you're just copying them so something like this should work:
#include <iostream>
using namespace std;
void copy_array (const int [], int []); //function prototype
int main()
{
//Your arrays
int arr[10];
int values[10] = {1,2,3,4,5,6,7,8,9};
//Function call
copy_array(values, arr);
//Display contents of array
for(int i =0; i<10; i++){
cout << arr[i] << " " ;
}
return 0;
}
//Function definition
void copy_array (const int values[], int arr[]){
for (int i =0; i<10; i++){
arr[i] = values[i];
}
}
Output
1 2 3 4 5 6 7 8 9 0
Also, your array size should be a constant integer variable.
you probably don't want to return arrays like never, because it could mean a lot of useless copy, which slows down your program, but
you could always write a function that copies values from one array to another
#include <iostream>
void assignarray(int *dest, int *src, size_t size)
{
for (size_t i = 0; i < size; ++i)
{
dest[i] = src[i];
}
}
int main()
{
int arr[10];
int values[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
assignarray(arr, values, sizeof(values) / sizeof(int));
for (size_t i = 0; i < 10; i++)
{
std::cout << values[i] << " ";
}
}
output:
1 2 3 4 5 6 7 8 9 10
Return type of a function cannot be an array.
However, array can be member of a class, and class can be return type of a function, so it is possible to return a class object which wraps the array. The standard library has a template for such array wrapper. It is called std::array.
That said, returning an array (wrapped within a class) is not necessarily a good design. Sometimes it is better to let the caller create the container - and indeed, they can choose the type of the container that they wish to use - and pass that into a template function to be filled. Here is an example of accepting a range:
template<class Range>
void fill(Range& r) {
assert(std::ranges::distance(r) == 10);
int values[10] = {1,2,3,4,5,6,7,8,9};
int i = 0;
for (auto& e : r)
{
e = values[i++];
}
}
// example
int arr[10];
fill(arr);

Could someone show me how this is implemented in main()? (question on void pointers) [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I got the below snippet from Algorithms in a nut shell
void sortPointers (void **ar, int n,
int (*cmp)(const void *, const void *)) {
int j;
for (j = 1; j < n; j++) {
int i = j-1;
void *value = ar[j];
while (i >= 0 && cmp (ar[i], value) > 0) {
ar[i+1] = ar[i];
i--;
}
ar[i+1] = value;
}
}
https://www.amazon.com/Algorithms-Nutshell-OReilly-George-Heineman/dp/059651624X
They do not provide the main() implementation of
sortPointers
so i have some problems figuring out what does **ar do
when i attempted to do a test code on
**arrPtr = x
it returns the error that you cannot cast void ** on a int *.
this surprises me as the book clearly says you feed an array into the function.
int main()
{
var x[3] = { 2 , 4 , 3};
void **arrPtr = x[0];
return 0;
}
a side question as well.
void *value = ar[j];
is this a unneeded step? the CMP function was able to take ar[i] as a argument, shouldnt it be able to take ar[j] as is?
In C we have the function qsort which is a generic function to sort arrays. It can sort all kind of arrays (e.g. arrays of int, arrays of double and even arrays of custom structs). All it requires is that the user provide a "compare" function for comparing two elements.
The sortPointers seems to be pretty much the same except it does not sort arrays of elements but instead sorts an array of pointers to elements.
As far a I can see the idea is to use it like:
#include <stdio.h>
#include <stdlib.h>
int cmp(const void * a, const void * b)
{
int* pa = (int*)a;
int* pb = (int*)b;
if (*pa > *pb) return 1;
if (*pa < *pb) return -1;
return 0;
}
void sortPointers (void **ar, int n,
int (*cmp)(const void *, const void *))
{
int j;
for (j = 1; j < n; j++) {
int i = j-1;
void *value = ar[j];
while (i >= 0 && cmp (ar[i], value) > 0) {
ar[i+1] = ar[i];
i--;
}
ar[i+1] = value;
}
}
void pp(int **ar, int n)
{
for(int i=0; i<n; ++i)
printf("Address %p holds the value %p and points to %d, i.e. arr[%d] points to %d\n", (void*)(&ar[i]), (void*)ar[i], *ar[i], i, *ar[i]);
}
#define ELEM 3
int main(void)
{
int* arr[3];
for(int i=0; i<ELEM; ++i) arr[i] = malloc(sizeof(int));
*arr[0] = 5;
*arr[1] = 8;
*arr[2] = 2;
pp(arr, ELEM);
sortPointers((void**)arr, ELEM, cmp);
printf("------------------------\n");
pp(arr, ELEM);
for(int i=0; i<ELEM; ++i) free(arr[i]);
return 0;
}
Output:
Address 0x7fff9a7d0270 holds the value 0xeeb010 and points to 5, i.e. arr[0] points to 5
Address 0x7fff9a7d0278 holds the value 0xeeb030 and points to 8, i.e. arr[1] points to 8
Address 0x7fff9a7d0280 holds the value 0xeeb050 and points to 2, i.e. arr[2] points to 2
------------------------
Address 0x7fff9a7d0270 holds the value 0xeeb050 and points to 2, i.e. arr[0] points to 2
Address 0x7fff9a7d0278 holds the value 0xeeb010 and points to 5, i.e. arr[1] points to 5
Address 0x7fff9a7d0280 holds the value 0xeeb030 and points to 8, i.e. arr[2] points to 8
However, the whole function seems to be a waste of time. The standard qsort can do this for you so why write a special function? As written above qsort can sort all kind of arrays so it can also sort an array of pointers. The compare function just needs to be a bit different. Simply use qsort like:
// Compare function
int cmp_qsort(const void * a, const void * b)
{
int** pa = (int**)a;
int** pb = (int**)b;
if (**pa > **pb) return 1;
if (**pa < **pb) return -1;
return 0;
}
// Call from main like:
qsort(arr, ELEM, sizeof(int*), cmp_qsort);
The output will be the same (except for the address that change every time you run it) and you don't need a custom sort function like sortPointers.

Return an array of compared char pointers in C++ [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 8 years ago.
I'm at college and we're learning pointers. Our job was to input a char, compare it to an array and return a pointer to the first reference of that char in the array. But, as I don't like easy things, I've asked my teacher what about having that char more than once in the array.
That's where my headache begins.
So I have this code. The idea is: create a function that compares the input char to the entire array, get the pointers of the references and save them in an array and return that array.
Unfortunately it's not working as I wish :(
What can be wrong?
#include<iostream>
#include<cstdlib>
using namespace std;
char list [10];
int main()
{
initialize();
show();
cout<<search('1');
}
void initialize()
{
int i;
for(i=0; i<10;i++)
{
list[i]='1';
}
}
void show()
{
int i;
for(i=0; i<10;i++)
{
cout<<list[i];
}
}
int* search(char* input)
{
int* result[10];
int i;
char *temp;
for (i=0; i<10; i++)
{
*temp=list[i];
if(strcmp(temp, input) != NULL)
{
result[i]=i;
}
}
return result[];
}
I'm on a mobile device so I can't go into huge detail unfortunately, but you are returning a pointer to an array that you create in the function which goes out of scope at the end of the function.
My massive edit:
As everyone has already stated, a C++ array is actually only a pointer to the first element in the array. As a result, if you return a pointer to an array created in the scope of the function, you are returning a pointer to garbage. If I were doing this I would use a vector, but if I were to be forced into using an array, I would use something like the code below. Hope this helps!
#include <iostream>
#include <cstdlib>
void initialize(char* list) {
for(int i = 0; i < 10; ++i) {
if(i < 4) {
list[i] = '2';
} else {
list[i] = '1';
}
}
}
void show(char *list) {
for(int i = 0; i < 10; ++i) {
std::cout << list[i] << ' ';
}
std::cout << std::endl;
}
// Note the function requires an additional argument that is a pointer
// this is how you can avoid returning a pointer
int search(char input, char* list, char* result) {
int j = 0;
for(int i = 0; i < 10; ++i) {
// comparing characters can be done via ==
if(input == list[i]) {
*(result + j) = list[i];
// You could use result[j], but I used this to show that
// result really is just a pointer to the first element
// of the array. As a result saying result[j] is the same
// as saying I want to deference j elements past the first
// element or *(result + j)
++j; // increment j
}
}
// return how many elements matched
return(j);
}
int main(int argc, char *argv[]) {
char list[10];
char temp[10];
initialize(list);
show(list);
int size = search('1', list, temp);
// create a dynamically sized array containing space for each match
// because we don't know the size at compile time we must use
// a library type or a dynamically sized array
char *result = new char[size];
for(int i = 0; i < size; ++i) {
result[i] = temp[i];
// again you could use result[i]
std::cout << *(result + i) << std::endl;
}
delete[] result; // otherwise you'll get a memory leak
return(0);
}