I wrote a program for my assignment that involves pointers and dynamic allocation for an array, I am getting a runtime error and the program crashes, there are no compiling errors. Here is the program :
array.h :
#include <iostream>
using namespace std;
void readArray(float*, int &);
void PrintArray(float*, int);
array.cpp :
#include "array.h"
void readArray(float* array, int &size)
{
array = new float[size];
cout << endl;
cout << "Enter the array elements, use spaces: ";
for (int i = 0; i < size; i++)
{
cin >> array[i];
}
cout << endl;
}
void PrintArray(float * array, int size)
{
for (int i = 0; i < size; i++)
{
cout << array[i] << " ";
}
cout << endl;
}
main.cpp :
#include "array.h"
int main()
{
int size = 0;
cout << "How many elements would you like to enter? ";
cin >> size;
cout << endl;
float *array = NULL;
readArray(array,size);
cout << "The array size is " << size << endl;
PrintArray(array, size);
return 0;
}
Sample Output :
How many elements would you like to enter? 3
Enter the array elements, use spaces: 4.0 5.0 6.0
The array size is 3
Crashes here
Can someone let me know what the problem is with the PrintArray function?
The parameter array of readArray() is passed by value, so array in main() remains NULL even if you changed it in readArray(). To make it be passed by reference. In addition, size doesn't need be passed by reference.
change
void readArray(float* array, int &size)
to
void readArray(float*& array, int size)
Q: Can someone let me know what the problem is with the PrintArray function?
A: Your PrintArray function is fine.
The problem is that you never pass the array you've allocated outside of readArray.
BETTER:
float *
readArray(int size)
{
float* array = new float[size];
cout << endl;
cout << "Enter the array elements, use spaces: ";
for (int i = 0; i < size; i++)
{
cin >> array[i];
}
cout << endl;
return array;
}
int main()
...
float *array = readArray(size);
...
NOTES:
If you declared a prototype for readArray() in array.h, you'll need to update it.
There are many ways to accomplish this, but the basic problem is you need ** (a pointer to a pointer) instead of * if you allocate your array inside the function. I believe passing the array pointer back as a function return is arguably the cleanest solution.
IMHO...
Related
I am trying to make functions to call in the main function, trying to keep "main" as clean as possible.
so I made a function to get the size array from the user then the user enters the elements of the function, but I got stuck at the linear search function, so want help "Still absolute beginner"
#include <iostream>
using namespace std;
int* Array_Elements () {
static int arr [5] {}, i, size;
cout << "Enter Array size: ";
cin >> size;
cout << "Enter Array Elements: " << endl;
for (i=0; i<size; i++) {
cin >> arr[i];
}
return arr;
}
void Array_Search (int arr [], int n) {
int temp = -1;
for (int i = 0; i < 5; i++) {
if (arr [i] == n) {
cout << "Element found at position: " << i + 1 << endl;
temp = 0;
break;
}
}
if (temp == -1) {
cout << "No Element Found" << endl;
}
}
int num () {
cout << "Please enter an element to search" << endl;
int num;
cin >> num;
return num;
}
int main () {
Array_Search (Array_Elements(), num());
return 0;
}
... trying to keep "main" as clean as possible.
Ok, thats a good motivation. Frankly, I find your main rather confusing. You try to do 3 seperate steps in one line and probably tripped over unspecified evalutation order of the function parameters. I have to admit, I don't remember if or in what version of C++ the order of evaluation of function parameters is specified. And I suggest you to not even try to remember it. Instead write code that does seperate steps in seperate steps.
Your main could look like this:
int main() {
auto arr = Array_Elements();
int number = num();
Array_Search(arr,number);
}
Even without a definition of Array_Elements(), num() or Array_Searcher one can get a rough idea of the three steps made here.
Next, global state is not clean. Your Array_Elements () cannot reasonably be called twice:
int* first_array = Array_Element();
int* second_array = Array_Element();
Both pointers would point to the same arr. The second call to Array_Element will overwrite what the first call assigned.
static int arr [5] {} as workaround to passing arrays around is a hack. It isn't the right way to solve that problem. Sloppy speaking it isn't any cleaner than a sphagetti main.
Use std::array when you want a stack allocated array with size known at compile time and std::vector for dynamic arrays. They can be passed between functions and you need not keep track of the size seperate from the array:
std::vector<int> Array_Elements() {
std::cout << "Enter Array size: ";
unsigned size = 0;
std::cin >> size;
std::vector<int> result(size);
std::cout << "Enter Array Elements: \n";
for (auto& element : result){
std::cin >> element;
}
return result;
}
The loop is a range based for-loop. In a nutshell, it iterates all elements in result and element is a reference to the elements.
Get acustomed to standard algorithms. They aren't doing something that you could not write yourself. Though, they help to write cleaner code, because instead of having several lines of code that all deal with one thing, "find an element", we can have one function call with a meaningful name: std::find.
void Array_Search(const std::vector<int>& arr,int n){
auto it = std::find(arr.begin(),arr.end(),n);
if (it == arr.end()) {
std::cout << "No Element Found\n";
} else {
std::cout << "Element found at position: " << (it - arr.begin()) << "\n";
}
}
In case the element was not found it returns the end iterator. When it does find the element we can calculate the index from an iterator by subtracting the begin iterator.
Live Demo
Lets jump right in, my suggestion to keep the main as clean as possible is to use a class then instantiate its object then use the object to call class methods in the main. This is best practice.
Your code confuses the compiler, in that the function num() precedes the function Array_Elements() in terms of order of evaluation. And I believe you want it the other way around.
Here's how to fix it: Remove the function num(), and make the following changes to your code
int* Array_Elements(int size) {
int* arr, i;
cout << "Enter Array Elements: " << endl;
arr = new int[size];
for (i=0; i<size; i++) {
cin >> arr[i];
}
return arr;
}
void Array_Search (int *arr, int size) {
int temp = -1, num;
cout << "Please enter an element to search" << endl;
cin >> num;
for (int i = 0; i < size; i++) {
if (arr [i] == num) {
cout << "Element found at position: " << i + 1 << endl;
temp = 0;
delete [] arr;
break;
}
}
if (temp == -1) {
cout << "No Element Found" << endl;
}
}
int main () {
int size;
cout << "Enter Array size: ";
cin >> size;
Array_Search(Array_Elements(size),size);
return 0;
}
The strange problem appears in my program. It is working, but in debugging it shows the "Exception thrown" in random places at the outputting
cout<<"Average value:"<<u3.apr();
_getch();
Sometimes, it even throws this error after the main function (Behind the {})
It is quite annoying because the program just closes after 3 seconds because of these errors.
(Maybe that's because of class, but I'm trying to learn it ;) )
Have tried already changing lines order, rewriting class name and array name.
#include <iostream>
#include <conio.h>
using namespace std;
class vid
{
private:
int i, j;
double rez, sum=0;
public:
int size;
double *arr = new double[size];
double apr()
{
for (i = 0; i < size; i++)
{
sum += (*(arr + i));
}
return sum / size;
}
};
int main()
{
vid u3;
cout << "Enter array length:";
cin >> u3.size;
for (int i = 0; i < u3.size; i++)
{
cout << "Enter array's " << i << " element:" << endl;
cin >> *(u3.arr+i);
}
cout << "Your array:" << endl;
for (int i = 0; i < u3.size; i++)
{
cout << *(u3.arr + i) << "\t";
}
cout << endl;
cout<<"Average value:"<<u3.apr();
_getch();
}
Thanks for any help ;)
arr is initialised when u3 is constructed.
But you didn't populate u3.size until later.
So, your array has indeterminate length (which is already UB), and your accesses later may be invalid.
You're going to have to manage your class's member a bit more cleverly!
Such classes generally have a "resize" function that performs the allocation per the requested size. Don't forget to safely kill any prior allocation, transplanting data if necessary. You can find online plenty of examples of a vector implementation.
Certainly renaming classes and randomly re-ordering the lines of your program's source code is not going to solve anything.
u3.size is not set until after u3 is constructed. By setting u3.size you can avoid this compiler-time error.
It seems that as an alternative solution, you might want to consider how to get rid of the new call and the need to write a destructor that will delete arr.
By creating a constructor that takes a size parameter AND by switching arr to a std::vector, you can allow the class to hold the vector and handle memory allocation and deallocation:
#include <iostream>
#include <vector>
using namespace std;
class vid
{
private:
int i, j;
double rez, sum=0;
public:
int size;
std::vector<double> arr;
// constructor requires size to be passed in;
// constructor initializes the arr array with the passed in size to zeroes.
vid(int argSize) : size(argSize), arr(argSize, 0.0){ }
double apr()
{
for (i = 0; i < size; i++)
{
sum += arr[i];
}
return sum / size;
}
};
int main()
{
uint size;
cout << "Enter array length:";
cin >> size;
vid u3(size);
for (int i = 0; i < u3.size; i++)
{
cout << "Enter array's #" << i << " element:" << endl;
cin >> u3.arr[i];
}
cout << "Your array:" << endl;
for (int i = 0; i < u3.size; i++)
{
cout << u3.arr[i] << "\t";
}
cout << endl;
cout<<"Average value:"<<u3.apr();
char ch;
cin >> ch;
}
so I have made a program that works in the following way.
user decides how big the array is.
user then fills the array with x chosen integers, e.g. if they choose to make an array 5 large, they are then asked to fill the array with 5 numbers. However I'm a little stuck on how I can do this, once this bit is done everything else should work I believe as I have tested it by hard coding it with assigned values and the function dose reverse the program.
Here is my code.
#include <iostream>
using std::cout;
using std::endl;
using std::cin;
void reverse(int [], int);
void printarray(int [], int );
void printarray(int arr[], int count)
{
for(int i = 0; i < count; ++i)
cout<<arr[i]<<' ';
cout<<'\n';
}
void reverse(int arr[], int count)
{
int temp;
for (int i = 0; i < count/2; ++i)
{
temp = arr[i];
arr[i] = arr[count-i-1];
arr[count-i-1] = temp;
}
}
int main ()
{
int x;
cout << "how big is this thing " << endl;
cin >>
const int SIZE = x;
int arr [SIZE] = {., ., ., ., ., ., ., . , ., .};
cout<<"Before reverse\n";
printarray(arr, SIZE);
reverse(arr, SIZE);
cout<<"After reverse\n";
printarray(arr, SIZE);
return 0;
}
I do believe that I have to use a for loop or something to repeat and enter the integers into each index of the array, sorry it's been so long since I have done arrays.
Any help with this issue would be greatly appreciated.
You can try the following..
#include <iostream>
#include <string>
void reverse(int arr[], int count)
{
int temp;
for (int i = 0; i < count/2; ++i)
{
temp = arr[i];
arr[i] = arr[count-i-1];
arr[count-i-1] = temp;
}
}
void print_array(int my_array[], int array_size)
{
std::cout << "Your array: ";
for (int x = 0; x <array_size; x++) {
std::cout << my_array[x] << " ";
}
std::cout << std::endl;
}
int main()
{
int array_size;
std::cout << "how big is this thing " << std::endl;
std::cin >> array_size;
int my_array[array_size];
std::cout << "Please enter the elements of the array. Press ENTER after each element." << std::endl;
for (int x = 0; x <array_size; x++) {
std::cin >> my_array[x];
}
print_array(my_array, array_size);
std::cout << "Reverse array..." << std::endl;
reverse(my_array, array_size);
print_array(my_array, array_size);
}
This sounds like a homework exercise? In most cases you would be using something like std::vector but I guess for this you will need to be sticking to native arrays.
int arr[SIZE];
This will create an array on the stack, and the size must be known at compile time. If you don't know the size until runtime you will need allocate the array on the heap using the new keyword (or via something like malloc)
int *arr = new int[x];
You'll need to free this memory yourself once you're done though
delete[] arr;
That should be enough to get you started and point you int right direction. Hope that helps
Cause the size of array is unknown at compile time you can not use int array[SIZE] construct.
You need to allocate the memory at run-time with new:
int x;
cout << "how big is this thing " << endl;
cin >> x;
int *arr = new int[x];
for(int i = 0; i < x; i++) {
cout << "enter arry[" << i << "]" << endl;
cin >> arr[i];
}
cout<<"Before reverse\n";
printarray(arr, SIZE);
reverse(arr, SIZE);
cout<<"After reverse\n";
printarray(arr, SIZE);
delete[] arr;
The delete[] arr operator frees the allocated array. You should free every allocated memory blocks to avoid memory-leaks.
As mentioned from M.M, use std::vector and insert to the beginning of the vector (you don't need you're reverse)
#include <iostream>
#include <vector>
int main(int argc, char** argv)
{
std::vector<int> values;
int n_values;
std::cout << "How mutch numbers ?";
std::cin >> n_values;
std::cout << "Now Enter " << n_values << " Values : ";
for(auto i=0; i<n_values; i++)
{
int tmp;
std::cin >> tmp;
values.insert(values.begin(), tmp);
}
for(auto elem : values)
std::cout << elem << "\n";
return 0;
}
So I have written a function that should simply add the values of each element stored in two separate arrays, and save them to a third array.
I don't understand what the issue is, I am simply adding together the value of the int stored at the location referenced by each of my pointers, and saving it to my third, empty, array.
My code compiles just fine, but when I loop to print the contents of my third array (which should contain the sum of the two previous arrays elements at their respective indexes) it just prints a bunch of memory addresses. What gives?
EDIT: I fixed my while loop to perform the arithmetic, and everything is working well. My working code is below. Hope it helps someone else.
#include<iostream>
#include<stdlib.h>
using namespace std;
void arrayAdd(int firstArray[], int secondArray[], int targetArray[], int size){
int *firstPtr = firstArray;
int *secondPtr = secondArray;
int *tragetPtr = targetArray;
while (firstPtr <= &firstArray[size - 1] ){
//add the first two array elements
*tragetPtr = (*firstPtr + *secondPtr);
// point to the next location
*firstPtr++;
*secondPtr++;
*tragetPtr++;
}
}
int main() {
int totalElements;
const size_t ARRAY_SIZE = 50;
int firstIntegerArray[ARRAY_SIZE];
int secondIntegerArray[ARRAY_SIZE];
int thirdIntegerArray[ARRAY_SIZE];
cout << "Please enter the total number of elements for your array: ";
cin >> totalElements;
for(int i = 0; i < totalElements; i++){
cout << "Please enter a value for the first array at index " << i << ": ";
cin >> firstIntegerArray[i];
}
for(int i = 0; i < totalElements; i++){
cout << "Please enter a value for the second array at index " << i << ": ";
cin >> secondIntegerArray[i];
}
//run our arrayAdd function
arrayAdd(firstIntegerArray, secondIntegerArray, thirdIntegerArray, totalElements);
cout << "The conents of your two arrays added together is; " << endl;
for(int i = 0; i < totalElements; i++){
cout << thirdIntegerArray[i] << ", ";
}
return 0;
}
A local array decays to a pointer when it is passed to a function, so you can't use sizeof on it anymore. Indeed this:
void arrayAdd(int firstArray[]) {
int *firstPtr = firstArray;
std::cout << "sizeof(firstArray) == " << sizeof(firstArray) << std::endl;
std::cout << "sizeof(firstPtr) == " << sizeof(firstPtr) << std::endl;
}
int main() {
int test[] = {1,2,3,4,5,6,7,8,9,0};
arrayAdd(test);
return 0;
}
Prints:
sizeof(firstArray) == 8
sizeof(firstPtr) == 8
on my 64 bit machine.
Casting int[] to int* doesn't change anything since it already became a pointer as an argument. You should pass the size of the array to the method or, since you are working with C++, use an std::array or std::vector which will just solve any problem.
My program should fill up and show an array. It should also calculate average value in the array.
The program stops at this line:
cin >> *f1[j];
I think it's the problem line, but I could have made mistakes elsewhere.
#include <iostream>
using namespace std;
// prototypes
void add(int*f[],int h);
void show(int*f[],int h);
int average(int*f[],int h);
int main()
{
// getting size of a array
cout << "How many numbers would you insert? : ";
int i = 0;
cin >> i;
cout << endl;
// the dinamic array
int * arr = new int[i];
// call functions
add(&arr, i);
show(&arr, i);
average(&arr, i);
// deleting the dinamic array
delete[] arr;
system("pause");
return 0;
}
// declaring of the functions
// this function should fill up the array
void add(int* f1[], int h)
{
for(int j = 0 ; j < h ; j++)
{
cout << "Insert " << j+1 << ". value : ";
cin >> *f1[j]; //this should be the problem
cout << endl;
}
}
// this function should show the array
void show(int *f2[], int h)
{
for(int j = 0 ; j < h ; j++)
{
cout << *f2[j] << ", ";
}
}
// this function should should show average value of the array
int average(int *f3[], int h)
{
int n = 0;
for(int j = 0 ; j < h ; j++)
{
n += *f3[j];
}
n /= h;
return n;
}
You aren't referencing your arrays correctly. p* points to index p[0]
cout << *f2[j] << ", ";
should be
cout << f2[j] << ", ";
It compiles and runs with the edits I made.
http://ideone.com/DsxOOP
Also, You aren't taking any inputs.
You'll need to:
use int* fX in your function signatures
drop the & referencing from your function calls (you already have a memory address stored in arr and there's no such thing as a memory address for another memory address)
not use * dereferencing within your functions (you're already dereferencing the array with [] indexing)
http://pastebin.com/xY7A6JvE compiles and runs.