Dynamically allocated array - c++

I'm learning pointers in but I'm stuck on dynamic allocation of arrays.
The code below provides a function to find the element with the lowest value.
A dynamically allocated array is passed as a parameter to it.
#include <cstdlib>
#include <iostream>
using namespace std;
int findMin(int *arr, int n);
int main()
{
int *nums = new int[5];
int nums_size = sizeof(*nums);
cout << "Enter 5 numbers to find the minor:" << endl;
for(int i = 0; i < nums_size; i++)
cin >> nums[i];
cout << "The minor number is " << findMin(*nums, nums_size);
delete [] nums;
return 0;
}
But it return this error:
error: invalid conversion from ‘int’ to ‘int*’ [-fpermissive]
How can I pass that array to the function?
Just for curiosity: why the for loop allows me to enter 4 value if my array is made up of 5 elements?

How can I pass that array to the function?
nums is already a type int*, you don't need to dereference it:
findMin(nums, nums_size);
why the for loop allows me to enter 4 value if my array is made up of 5 elements?
int nums_size = sizeof(*nums); does not do what you think it does. It's equivalent to sizeof(nums[0]), which is equivalent to sizeof(int), which happens to be equal to 4 at your machine.
There is no way to extract size of array allocated on the heap, you need to save the size on your own:
int nums_size = 5;
int* nums = new int[nums_size];

#include <cstdlib>
#include <iostream>
using namespace std;
int findMin(int *arr, int n){
int mn=INT_MAX;
for(int i=0;i<n;i++){
if(arr[i]<mn){
mn=arr[i];
}
}
return mn;
};
int main()
{
int nums_size = 5;
int *nums = new int[nums_size];
cout << "Enter 5 numbers to find the minor:" << endl;
for(int i = 0; i < nums_size; i++)
cin >> nums[i];
cout << "The minor number is " << findMin(nums, nums_size);
delete [] nums;
return 0;
}
The above code works fine. Your error was in passing the array to the function.
Also to add -
Your code made only 4 iterations coz sizeof(*nums) returned the size of base index element pointed by pointer, i.e ,sizeof(num[0]). So I made a minor change and now it works fine.

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.

Problem using iterators with dynamically allocated array

I have a variable k of type int to set the length of a dynamically allocated int array:
int *Numbers = new int[k];
But because of this I cannot iterate over the array, I get an error:
"no matching begin function was found required for this range-based for statement"
I also cannot get the length of the array using size();
Here's the complete code:
#include <iostream>
using namespace std;
int main()
{
int b, k;
cin >> b >> k;
int *Numbers = new int[k];
for (int i : Numbers) {// (There is a error)
}
for (int i = 0; i < size(Numbers); i++) {
}
}
Prefer using a std::vector instead of a std::array. (Like #tadman mentioned.)
Here is your code using std::vector instead:
#include <iostream>
#include <vector>
int main()
{
int b, k;
std::cin >> b >> k;
std::vector<int> Numbers(b,k); // Fills the vector "Numbers" with nth number of elements with each element as a copy of val.
for (int i : Numbers)
std::cout << i << std::endl;
for (int i = 0; i < Numbers.size(); i++)
std::cout << Numbers[i] << std::endl;
return 0;
}
Say I want 10 elements with the number 5.
Output:
10
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
Also consider not using namespace std;.
The simple and recommended solution is to use std::vector, however if you really want a dynamically allocated array and to use iterator like features on it, you can use iterator_range from boost library, which allows you to create an iterator range for it thus making it usable in range based for loops and in functions like std::size.
Live demo
#include <iostream>
#include<boost/range.hpp>
int main()
{
int k = 5;
int *Numbers = new int[k]{1,4,5,7,8};
auto arr = boost::make_iterator_range(Numbers, Numbers + k);
for (int i : arr) { //range based loop
std::cout << i << " ";
}
std::cout << std::endl << "Size: " << arr.size(); //print size
//or std::size(arr);
}
Output:
1 4 5 7 8
Size: 5
Range-based for loops work with arrays, but not work with pointers. The Actual issue is that arrays is actually a pointer and not an array.try to use simple array.
Using pointers is problematic for many reasons. The simple solution to your problem is to use a vector
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int b, k;
cin >> b >> k;
vector<int> Numbers(k);
for (int i : Numbers) {
cout << i << endl;
}
for (int i = 0; i < Numbers.size(); i++) {
cout << Numbers[i] << endl;
}
}
C array does not have default iterator and thus there is no begin() and end() functions that are used to iterate over array when you use statment like this:
for (int i : Numbers)
You can check range-for reference:
range_expression - any expression that represents a suitable sequence (either an array or an object for which begin and end member functions or free functions are defined, see below) or a braced-init-list.
Okay, so since the dynamic array does not have a default iterator, do not use the for-each loop, instead consider using the regular for loop.
Also, mind the the size function will not work for an array (or dynamic array) and you need to remember the size, since it's not possible to get the size from the pointer only. Hence, this code would work:
#include <iostream>
using namespace std;
int main()
{
int b, k;
cin >> b >> k;
int *Numbers = new int[k];
const int SIZE = k;
for (int i = 0; i < SIZE; i++) {
cout << i << ' ';
}
}
You need to dereference *Numbers by using the * if you want to iterate over the array because *Numbers is a pointer to an integer which points to the first element of your array.For Example :
#include <iostream>
using namespace std;
int main()
{
int k = 10;
int *numbers = new int[k];
//filling the array
for(int i = 0 ; i < k ; ++i) {
*(numbers + i) = i ;
}
//output array element
for(int i = 0 ; i < k ; ++i) {
cout << numbers + i << " is the address of "<<*(numbers + i) << endl;
}
return 0;
}
The output is :
0x6f1750 is the address of 0
0x6f1754 is the address of 1
0x6f1758 is the address of 2
0x6f175c is the address of 3
0x6f1760 is the address of 4
0x6f1764 is the address of 5
0x6f1768 is the address of 6
0x6f176c is the address of 7
0x6f1770 is the address of 8
0x6f1774 is the address of 9
Unfortunatly, you can't get the size of your array with *Numbers because it's not an array but a pointer.

How do I find highest value using pointer?

I want to find the highest value from an array using two given pointer int *p,*max;, but the code doesn't work.
#include <iostream>
#include <string>
using namespace std;
int main() {
int a[10], i, index;
int *p, *max;
for (i = 0; i < 10; i++) cin >> a[i];
max = 0;
p = &a[10];
for (index = 0; index < 10; index++) {
if ((p[index]) > *max) {
*max = (p[index]);
}
}
cout << "Highest value=" << *max << endl << "is at index=" << index << endl;
return 0;
}
The code is buggy. First of all, you assign
p=&a[10];
This assigns p to a memory address past a. Furthermore, you then index as p[index], which essentially is the same as a[10 + index].
Also, max is a wild pointer. It does not point to anything. You are assigning values to an undefined memory location.
I would strongly suggest to read up on pointers and to properly understand them before using them. Also, in modern C++, it is not very often than you need pointers.
Also, in idiomatic C++, we would probably write
auto p = std::max_element(a, a + 10);
There are several problems.
First, p should point to the array's first element, so you should have p = &a[0].
You can also rely on implicit conversion and just write p = a;, which is exactly the same.
&a[10] is the pointer "one-past-the-end" of the array, and dereferencing it is undefined.
Next, you want max to point to the maximum element.
It should also start at the beginning of the array, like p.
Then, when you find a new maximum, you should make max point to that element, not change the value max points to.
Lastly, index will always be 10 after the search loop.
(Take a few moments to think about why.)
You don't need it – the index is the difference between the location of the maximum element and the beginning of the array.
int main()
{
int a[10];
for(int i = 0; i < 10; i++)
cin >> a[i];
int* max = &a[0];
int* p = &a[0];
for (int index = 0; index < 10; index++){
if (p[index] > *max){
max = &p[index];
}
}
cout << "Highest value= " << *max << endl << "is at index= "<< max - a << endl;
}
I'd remove p and use a range-based for-loop where possible and iterators when it'll improve performance.
Comments in the code:
#include <iostream>
#include <iterator>
// using namespace std; // don't do this
int main() {
using std::cin, std::cout;
int a[10];
// use a range-based for-loop:
for(int& aref : a) { // aref is a reference to the current element in a
// check that extraction from std::cin actually works
if(!(cin >> aref)) {
std::cerr << "error reading int\n";
return 1;
}
}
// initialize max to point at the first element
auto max = std::begin(a);
// Start at the second element since max is already set to point at the first element.
// Don't use magic numbers. Define a constant or use std::size(<array>)
// ...or use iterators like in this example:
for(auto curr = std::next(std::begin(a)); curr != std::end(a); ++curr) {
if(*curr > *max) {
max = curr;
}
}
// you can use std::distance ot calculate the index for max:
cout << "Highest value=" << *max << '\n'
<< "is at index=" << std::distance(std::begin(a), max) << '\n';
}
The solution to this problem is recognizing that max should always point to the maximum item seen in the array a so far so instead of initializing max to 0 you start by initializing it to point to the first item in a which is &a[0] or just a.
I tried to make the least amount of changes to the original code:
#include <iostream>
#include<string>
using namespace std;
int main()
{
int a[10],i,index;
int *p,*max;
for(i=0;i<10;i++)
cin>>a[i];
max=a; // Initialize max to point to the first item in a
p=a;
for(index=0;index<10;index++){
if((p[index])>*max){
max=(&p[index]); // Now make max point to the new maximum item
}
}
cout<<"Highest value="<<*max<<endl<<"is at index="<<max - p<<endl;
return 0;
}
Here is the code in ideone:
https://ideone.com/BwE45C
As mentioned in the comments below p probably is not being used as the question expects so I have rewritten the code to iterate using p
#include <iostream>
#include<string>
using namespace std;
int main()
{
int a[10],i,index;
int *max;
for(i=0;i<10;i++)
cin>>a[i];
max=a;
for(int* p=a;p<a+10;p++){ // p is now a pointer that is used to iterate through the array
if(*p>*max){
max=p; // max points to the new maximum
}
}
cout<<"Highest value="<<*max<<endl<<"is at index="<<max - a<<endl;
return 0;
}
The new ideone link for this is here: https://ideone.com/bk3zoS

returning an array address from function in c++ issue

i'm new to programming , this code gives me syntax error in line => int *result = apply_all(array1,5,array2,3) this is the error: expected primary-expression before '}' token|
i'm trying to write function called apply_all expects 2 arrays of integers and their sizes and dynamically allocates a new array of integers whose size is the product of 2 array sizes.
the function should loop through the 2nd array and multiple each element accross each element of array 1 and store the product in newly created array. the function is returning a pointer of to the newly allocated array.
also i wrote a function which is print to display the 1st & 2nd & newly array.
#include <iostream>
using namespace std;
//function prototype
int *apply_all(int *array1 ,int size1,int *array2,int size2);
void print(int *array,int size);
int main()
{
int array1[] {1,2,3,4,5};
int array2[] {10,20,30};
cout << "Array 1:";
print(array1,5);
cout << "Array 2:";
print(array2,3);
int *result = apply_all(array1,5,array2,3);
cout << "Result : ";
print(result,15);
delete [] result;
return 0;
}
int *apply_all(int *array1 ,int size1,int *array2,int size2)
{
int *result {nullptr};
result = new int[size1 * size2];
for (int i{0};i<size2;i++)
for(int j{0};j<size1;j++)
*(result[i*5+j]) = *(array1[i])**(array2[j]);
return result;
}
void print(int *array,int size)
{
for(auto num:array)
cout << num << endl;
}
On this line:
*(result[i*5+j]) = *(array1[i])**(array2[j]);
since result[i*5+j] gives you an int, you are trying to dereference an int, which is not possible.
You just need to do:
result[i*5+j] = array1[i] * array2[j];
Also, in print, your range-for loop won't work with a pointer. You need to do:
for(int i = 0; i < size; ++i)
cout << array[i] << endl;
Also, in apply_all, your loop bounds are incorrect. i needs to go till size1, and j needs to go to size2.
Here's a demo.
Since you are new, a simple work around would be creating an array with buffer space to store your results in and passing the pointer for this into apply_all. You could then write to this array which (being declared in main) should be very easy to access and cause few errors and use a c-string like ending to know when your results are over and to stop printing from the array (c-strings end with a value of 0 so that programs don't read unrelated memory). eg:
int buf[99];
apply_all(array_1, size1, array_2, size2, buf, size3);
for (int x = 0; buf[x] != end of buf var; x++;)
{
print(buf[x])
}
and
apply_all()
{
buf[start-end] = whatever you want;
buf[end + 1] = some variable that won't appear in buffer; //max int size?
}

How can I print the numbers in main function?

I am new to c++ language. I am trying to solve a problem using function. I have to print the pentagon numbers untill the integer input, but when function returns the values, it only prints one value. I would love some help with it.
#include<iostream>
using namespace std;
int pent(int num){
int p;
for(int i=1;i<=num;i++){
p=(i*(3*i-1)/2);
}
return p;
}
int main(){
int num;
cin>>num;
int sender=pent(num);
cout<<sender<<endl;
return 0;
}
Your function returns int, that is a single integer. To return more, you can use std::vector. As you probably are not familiar with it, I will give you some pointers...
The most simple constructor creates a vector with no entries:
std::vector<int> x;
You can reserve space for elements via reserve:
x.reserve(num);
The vector still has no elements, but it already allocated enough space to hold num elements. This is important, because when we will add elements the vector will grow and that potentially requires to copy all elements to a different place in memory. We can avoid such frequent reallocations by reserving enough space upfront.
To add elements to the vector you can use push_back:
x.push_back(42);
Eventually to print all elements of the vector we can use a range-based for loop:
for (auto element : x) std::cout << element << " ";
So you can rewrite your code like this:
#include <iostream>
#include <vector>
std::vector<int> pent(int num){
std::vector<int> result;
result.reserve(num);
for(int i=1;i<=num;i++){
result.push_back(i*(3*i-1)/2);
}
return result;
}
int main(){
int num;
std::cin >> num;
auto sender = pent(num);
for (auto number : sender) std::cout << number << " ";
}
In your program, from your pent() function you are only returning last calculated value. In you ever time, you are overwriting you variable p.
So there is a way which #asmmo is suggesting, to print in pent() function.
Or you can pass a vector to your pent() function and store values in that and print it in main function.
For your ref:
void pent(int num, vector<int> &arr) {
int p;
for (int i = 1; i <= num; i++) {
arr[i-1] = (i*(3 * i - 1) / 2);
}
}
int main() {
int num;
cin >> num;
vector<int> arr(num);
pent(num, arr);
for (int i = 0; i < num; i++) {
cout << arr[i] << endl;
}
return 0;
}