C++ pointers dynamic arrays and functions

This is from a beginning C++ class, no grade involved since I'm simply following along trying to remember stuff after too many years. The class has reached the point where we're using pointers and dynamic arrays. I'm trying to pass the array (or the pointer) to different functions having to do with various calculations on a list of integers. Some of the functions are working and others aren't. But I'm passing them all the same way and I'm calling them all the same way as well. Since some of the functions are returning garbage values, it feels like I'm not actually pointing where I think I am AND the functions that are working are only working by accident.

Before someone helpfully suggests that I should be using vectors and not arrays, the point of the exercise is to use dynamically allocated arrays.

Here's my code so far. It's the findavg() and findmedian() that are returning garbage.

#include <iostream>
#include <iomanip>

using namespace std;

void getarray(int *a, int &l)
{
    int input = 0;

    //-1 is not important here, just to make the while loop run
    while(input != '-1') 
    {
        cout << "Enter length of the list of numbers: ";

        if(!(cin >> input))
        {
            cout << "Please enter numeric characters only." << "\n";    
            //show error if they don't enter a number
            cin.clear();                                                
            //get rid of invalid characters
            cin.ignore(10000,'\n');
        }

        else if(input <= 0)
        {
            cout << "Please enter a number greater than 0." << "\n";    
            //show error if they enter a non-positive number
            cin.clear();                                                
            //get rid of invalid characters
            cin.ignore(10000,'\n');
        }
        else
        {
            l = input;  //input is a positive number
            break; //got good input, break out of while loop
        }

    }


    int i;
    int x; 

    cout << "Enter " << l << " integers on one line seperated by spaces.\n";


    for( i = 0; i < l  &&  cin >> x; ++i)
    {
        a[i] = x;
    }

}

void printarray(int *a, int &l)
{
    int i;

    cout << "The array of integers is:\n";
    for( i = 0; i < l; ++i)
        cout << setw(4) << a[i];
    cout << "\n";

}

int findmin(int *a, int &l)
{
    int min = 0;
    min = a[0]; 

    for(int i = 1; i<l; i++)
    {
        if(a[i] < min)
            min = a[i];
    }
    return min; 
}

int findmax(int *a, int &l)
{
    int max = 0;
    max = a[0];

    for(int i = 1; i<l; i++)
    {
        if(a[i] > max)
            max = a[i];
    }
    return max; 
}

float findavg(int *a, int &l)
{
    int total = 0;
    total = a[0];

    for(int i = 1; i<l; i++)
    {
        total = total + a[i];
    }

    return static_cast<float>(total/static_cast<float>(l));

}

float findmedian(int *a, int &l)
{
    int max = 0;
    int min = 0;

    max = findmax(a, l);
    min = findmin(a, l);

    return static_cast<float>((max + min)/2.0);

}


int main()
{

    int length = 0;
    int *an_array;

    an_array = new int[length];

    getarray(an_array, length);

    printarray(an_array, length);

    cout << "Maximum value in list is: "<< findmax(an_array, length) << "\n";
    cout << "Minimum value in list is: "<< findmin(an_array, length) << "\n";
    printf("Average is: %10.5f", findavg(an_array, length));
    cout << "\n";
    printf("Median is: %10.5f", findmedian(an_array, length));
    cout << "\n";

    delete [] an_array;

    return 0;
}

Answers


int length = 0;
int *an_array;

an_array = new int[length]; //What is this ?

You're allocating zero bytes for an_array, because length is 0. That is one problem I can see.

You should allocate memory for an_array in getarray function, after reading the length of array:

void getarray(int * &a, int &l) //see the change here!
{
    //code which reads length is omitted for brevity

    a = new int[l]; //alllocate memory after reading length

    //now read array elements here
}

Alternatively,you can write a struct as:

struct array
{
      int *data;
      size_t size;
};

And then use this everywhere. It is better because you tied the size and data together, and instead of using two independent objects, you can use just one object of type array, as described below.

array getarray() 
{
    array arr;

    //read length into arr.size

    arr.data= new int[arr.size]; //alllocate memory after reading length

    //now read array elements into arr.data

    return arr; //returning arr means you're returning both: data and size!
}

And then call this as:

 array arr = getarray(); //no need to pass any argument!

Also, if you're going to use this, then other functions signature would become:

void printarray(array arr);
int findmax(array arr);
float findavg(array arr);
float findmedian(array arr);

Now you need to modify these functions as well, but fortunately, there will not be major change : wherever you're using a and l, use arr.data and arr.size respectively instead. And you're done!

With all these improvements, your main() would become this:

int main()
{
    array arr = getarray();

    printarray(arr);

    cout << "Maximum value in list is: "<< findmax(arr) << "\n";
    cout << "Minimum value in list is: "<< findmin(arr) << "\n";

    printf("Average is: %10.5f\n", findavg(arr));
    printf("Median is: %10.5f\n", findmedian(arr));

    delete [] arr.data;
    return 0;
}

This looks better.


Need Your Help

Is it possible to use Apache Digester to filter dynamic xml leaf tags?

java xml blacklist apache-commons-digester

I've used Apache digester before and loved the branch based searching of xml tags.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.