Error in the void print function - c++

What I am trying to do is print out the elements that is dynamically allocated.
Here is my issue, I'm new in learning, and not understanding why this below cannot work? If you could please give a brief description why this is producing the error, I'm just trying to learn from my mistakes. I know I could just dynamically allocate the user input in the main function, but I wanted to see by trial and error if I could I just create an input function where I call it in my print function to produce the user elements after it is dynamically allocated.
Any suggestion on what I could do to make this work would be awesome, thanks.
void print(int* input, int size)
{
uinput(input,size);
for(int i=0; i<size;i++)
{
std::cout << " " << input[i];// Error -> Thread 1:EXC_BAD_ACCESS (code=1,address=0x0)
}
}
The entire code without the print function above
#include <iostream>
void print(int*, int);
void uinput(int*, int);
int* copy(const int*, int);
int main()
{
int size;
int* input;
std::cout << "Enter the size of the array";
std::cin >> size;
std::cout << "Original array:" << std::endl;
print(input,size);
int* expander = copy(input,size);
std::cout << "New array:" << std::endl;
print(expander,size);
delete [] input;
delete [] expander;
input= nullptr;
expander = nullptr;
return 0;
}
void uinput(int* input, int size)
{
int* uInput = new int[size];
for(int k=0; k <size;k++)
{
std::cin >> uInput[k];
}
}
int* copy(const int* input, int size)
{
int* newArray = new int[size*2];
int j =0;
for(int i = 0; i <size*2;i++)
{
if(j >i)
{
newArray[j]=newArray[i];
j++;
}
else
newArray[j]=0;
}
return newArray;
}
Update: I tried to modified where I just let it point to the size of uInput function, but that didn't work.
void uinput(int size)
{
int* uInput = new int[size];
for(int k=0; k <size;k++)
{
std::cin >> uInput[k];
}
}

Your uinput function allocates memory, but does not make use of the input parameter that you send it. As a result, trying to iterate over items supposedly pointed to by that pointer, which has not been initialized to point at anything, is undefined behavior, causing your program to crash, in this case.

Related

Calling a Function in a Class with Parameters C++

I'm practicing in order to better understand dynamic arrays and using them in a class. However, I'm struggling to call my functions inside the class. I have no issue with my int size variable, but my int myArray variable is giving me problems. I get the error "expected a member name" when I try to call my void functions in my main function. Are arrays not allowed to be used in this situation?
#include <iostream>
using namespace std;
class myClass
{
public:
int size;
int* myArray = new int[size];
void storeData(int& size, int (&myArray)[]);
void printData(int& size, int(&myArray)[]);
};
void myClass::storeData(int& size, int(&myArray)[])
// Stores array data.
{
cout << "Enter Size of the array: ";
cin >> size;
// User determines array size.
for (int x = 0; x < size; x++)
{
cout << "Array[" << x << "]: ";
cin >> myArray[x];
// User determines array values.
cout << endl;
}
}
void myClass::printData(int &size, int(&myArray)[])
// Displays values of the array.
{
cout << "Value of the arrays are: ";
for (int x = 0; x < size; x++)
{
cout << myArray[x] << " ";;
}
delete[]myArray;
}
int main()
{
myClass object;
object.storeData(object.size, object.(&myArray)[]);
// E0133 expected a member name.
object.printData(object.size, object.(&myArray)[]);
// E0133 expected a member name.
}
There are a couple issues here, I will try to address all of them.
When passing an array to a function, never use [] syntax. In C and C++, arrays decay to pointers, so we do not need [] nor &.
This is valid syntax to pass an array:
int my_array [] = {1,2,3,4};
my_function(my_array, 4);
...
void my_function(int * array, size_t size)
{
//Iterate over the array or do something...
}
In addition, if a function exists within a class, it can access class members freely, meaning we do not have to pass them in at all. See the following change to your code:
void myClass::storeData(int size)
// Stores array data. We do NOT need a pointer to the object array, we already have it!
{
cout << "Enter Size of the array: ";
cin >> size;
// User determines array size.
for (int x = 0; x < size; x++)
{
cout << "Array[" << x << "]: ";
cin >> myArray[x];
// User determines array values.
cout << endl;
}
}
Lastly, dynamic sized arrays must be allocated dynamically. Do not use int* myArray = new int[size]; in your class definition, because size is not yet initialized. Instead, use a constructor or use your store_data function to allocate the memory.
class myClass
{
public:
size_t size;
int * myArray; //Do not allocate anything here...
myClass(size_t size)
{
this->size = size;
myArray = new int[size];
}
};
You can get the size however you want, via user input, etc. and pass this to the constructor or an allocator function like storeData.

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?
}

Reverse Pointer function issue

I'm having an issue with the pointer return function. The error, "calling object type 'int* ' is not a function or a function pointer" reverseArray = reverseArray(array,size);.I am not sure why it's giving me this error, this is not my solution I'm using this solution as a guidance to help me solve the problem. Since I've sat for now 2 hours trying to solve it and I got no where with it, so I decide to look it up and get an idea on how to approach the problem. And break down their solution by using a debugger to see why their solution works. I know it's a bad thing to do because I'm not learning how to solve problems on my own.
#include <iostream>
int* reverseArray(int [], int );
int main()
{ const int size =5;
int array[size] = {1,2,3,4,5};
int* reverseArray;
for(int i =0; i < size;i++)
{
std::cout << array[i];
}
reverseArray = reverseArray(array,size);
for(int i =0; i <size;i++)
{
std::cout <<array[i];
}
return 0;
}
int* reverseArray(int array [],int size)
{
int* newArray;
newArray = new int[size];
int j = 0;
for(int k =size-1;k>=0;k--)
{
newArray[j] = array[k];
j++;
}
return newArray;
}
The error is self explanatory.
"calling object type 'int* ' is not a function or a function pointer". In you main() function, you named the array you want to pass as a parameter to your reverseArray() function with the same name as your function (reverseArray). The compiler get confused within that scope, because of this and thinks you're calling a variable as a function.
See below:
#include <iostream>
int* reverseArray(int [], int );
int main()
{ const int size =5;
int array[size] = {1,2,3,4,5};
int* reverseArray; // Change this name to something else
for(int i =0; i < size;i++)
{
std::cout << array[i];
}
reverseArray = reverseArray(array,size);
for(int i =0; i <size;i++)
{
std::cout <<array[i];
}
return 0;
}
Hope it helps :)

dynamic allocation of int array in c++ and assigning value

I am new to c++ and i was trying to do folloing two things without help of std::vector( This was done earlier)
Define an array of integer and the size of array is not known to me.
Pass this array into another function and output all the values stored in array.
int _tmain()
{
int* a = NULL;
int n;
std::cin >> n;
a = new int[n];
for (int i=0; i<n; i++) {
a[i] = 0;
}
testFunction(a,n);
delete [] a;
a = NULL;
}
void testFunction( int x[], int n)
{
for(int i =0;i<n;++n)
{
std::cout<<x[i];
}
}
But i can see that its not allocating memory of 10 bytes and all the time a single memory is filled up with 0.
Can anyone please help me if i am lacking something ? Or is there any alternative way for this apart from vector.
Thanks in Advance
I modified with one thing as i realized that i put ++n instead of i
int _tmain()
{
int* a = NULL;
int n;
std::cin >> n;
a = new int[n];
for (int i=0; i<n; i++) {
a[i] = i;
}
testFunction(a,n);
delete [] a;
a = NULL;
}
void testFunction( int x[], int n)
{
for(int i =0;i<n;++i)
{
std::cout<<x[i];
}
}
I’m not sure I understand all yours problems but the typo
for(int i =0;i<n;++n) in testFunction led to a very long loop.
Write:
for(int i =0;i<n;++i)
this print yours n "0"

Inputing the Size of a 2-dimentional Array

In my code I input the sizes of both dimensions and then declare a two-dimensional array. My question is, how do I use that array as a function parameter? I know that I need to write the number of columns in the function specification but how do I pass the number of columns?
void gameDisplay(gameCell p[][int &col],int a,int b) {
for(int i=0;i<a;i++) {
for(int j=0;j<b;j++) {
if(p[i][j].getStat()==closed)cout<<"C ";
if(p[i][j].getStat()==secure)cout<<"S ";
if(p[i][j].getBomb()==true&&p[i][j].getStat()==open)cout<<"% ";
if(p[i][j].getBomb()==false&&p[i][j].getStat()==open) {
if(p[i][j].getNum()==0)cout<<"0 ";
else cout<<p[i][j].getNum()<<" ";
}
cout<<endl;
}
}
}
int main() {
int row,col,m;
cout<<"Rows: ";cin>>row;cout<<"Columns: ";cin>>col;
m=row*col;
gameCell p[row][col];
gameConstruct(p[][col],m);
gameDisplay(p[][col],row,col);
}
I tried this way but it doesn't work.
Thank you.
In C++, you cannot have variable length arrays. That is, you can't take an input integer and use it as the size of an array, like so:
std::cin >> x;
int array[x];
(This will work in gcc but it is a non-portable extension)
But of course, it is possible to do something similar. The language feature that allows you to have dynamically sized arrays is dynamic allocation with new[]. You can do this:
std::cin >> x;
int* array = new int[x];
But note, array here is not an array type. It is a pointer type. If you want to dynamically allocate a two dimensional array, you have to do something like so:
std::cin >> x >> y;
int** array = new int*[x]; // First allocate an array of pointers
for (int i = 0; i < x; i++) {
array[i] = new int[y]; // Allocate each row of the 2D array
}
But again, this is still not an array type. It is now an int**, or a "pointer to pointer to int". If you want to pass this to a function, you will need the argument of the function to be int**. For example:
void func(int**);
func(array);
That will be fine. However, you almost always need to know the dimensions of the array inside the function. How can you do that? Just pass them as extra arguments!
void func(int**, int, int);
func(array, x, y);
This is of course one way to do it, but it's certainly not the idiomatic C++ way to do it. It has problems with safety, because its very easy to forget to delete everything. You have to manually manage the memory allocation. You will have to do this to avoid a memory leak:
for (int i = 0; i < x; i++) {
delete[] array[i];
}
delete[] array;
So forget everything I just told you. Make use of the standard library containers. You can easily use std::vector and have no concern for passing the dimensions:
void func(std::vector<std::vector<int>>);
std::cin >> x >> y;
std::vector<std::vector<int>> vec(x, std::vector<int>(y));
func(vec);
If you do end up dealing with array types instead of dynamically allocating your arrays, then you can get the dimensions of your array by defining a template function that takes a reference to an array:
template <int N, int M>
void func(int (&array)[N][M]);
The function will be instantiated for all different sizes of array that are passed to it. The template parameters (dimensions of the array) must be known at compile time.
I made a little program:
#include <iostream>
using namespace std;
void fun(int tab[][6], int first)
{}
int main(int argc, char *argv[])
{
int tab[5][6];
fun(tab, 5);
return 0;
}
In function definition you must put size of second index. Number of column is passed as argument.
I'm guessing from Problems with 'int' that you have followed the advices of the validated question and that you are using std::vector
Here is a function that returns the number of columns of an "array" (and 0 if there is a problem).
int num_column(const std::vector<std::vector<int> > & data){
if(data.size() == 0){
std::cout << "There is no row" << std::endl;
return 0;
}
int first_col_size = data[0].size();
for(auto row : data) {
if(row.size() != first_col_size){
std::cout << "All the columns don't have the same size" << std::endl;
return 0;
}
}
return first_col_size;
}
If you're using C-style arrays, you might want to make a reference in the parameter:
int (&array)[2][2]; // reference to 2-dimensional array
is this what you're looking for?
int* generate2DArray(int rowSize, int colSize)
{
int* array2D = new int[rowSize, colSize];
return array2D;
}
example . . .
#include <iostream>
#include <stdio.h>
int* generate2DArray(int rowSize, int colSize);
int random(int min, int max);
int main()
{
using namespace std;
int row, col;
cout << "Enter row, then colums:";
cin >> row >> col;
//fill array and display
int *ptr = generate2DArray(row, col);
for(int i=0; i<row; ++i)
for(int j=0; j<col; ++j)
{
ptr[i,j] = random(-50,50);
printf("[%i][%i]: %i\n", i, j, ptr[i,j]);
}
return 0;
}
int* generate2DArray(int rowSize, int colSize)
{
int* array2D = new int[rowSize, colSize];
return array2D;
}
int random(int min, int max)
{
return (rand() % (max+1)) + min;
}
instead of accessing p[i][j] you should access p[i*b + j] - this is actually what the compiler do for you since int[a][b] is flattened in the memory to an array in size of a*b
Also, you can change the prototype of the function to "void gameDisplay(gameCell p[],int a,int b)"
The fixed code:
void gameDisplay(gameCell p[],int a, int b) {
for(int i=0;i<a;i++) {
for(int j=0;j<b;j++) {
if(p[i*a +j].getStat()==closed)cout<<"C ";
if(p[i*a +j].getStat()==secure)cout<<"S ";
if(p[i*a +j].getBomb()==true&&p[i][j].getStat()==open)cout<<"% ";
if(p[i*a +j].getBomb()==false&&p[i][j].getStat()==open) {
if(p[i*a +j].getNum()==0)cout<<"0 ";
else cout<<p[i*a +j].getNum()<<" ";
}
cout<<endl;
}
}
}
int main() {
int row,col,m;
cout<<"Rows: ";cin>>row;cout<<"Columns: ";cin>>col;
m=row*col;
gameCell p[row][col];
gameConstruct(p[][col],m);
gameDisplay(p[],row,col);
}