This is one the methods that I have to make for my assignment
int*mode(int &) – returns an integer array containing the modal value(s) of the
population, the reference parameter should be set to the size of the result
But from searching, you cannot return array's from a function? I can calculate modal value from a given array, put it in an array, but return an integer array? maybe the professor meant something else? I know how to do all other methods except that one. I don't even know what that method means (Coming from java)
Header File
#include <string>
using namespace std;
class population
{
public:
//Default Constructor
population(void);
//Constructor that accepts an integer array object, and the size for that array object
population(int[], int);
//Constructor for creating a deep copy
population (const population &);
//For overloading purposes
population & operator = (const population &);
//Destructor that frees dynamic memory associated with the underlying array
~population(void);
//Method for loading new content into an array
void load(string);
//Method for adding new content into existing array
void add(string);
//Accessors
//Returns the size of the population (The number of values stored in the array)
int size();
//Returns the sum of the popluation (The sum of the contents in the array)
int sum();
//Returns the mean of the population
float mean();
//Returns the median of the population
float median();
//Returns the standard deviation of the population
float stddev();
//Returns an integer array containing the modal values of the popluation
int*mode(int &);
private:
int arraySize;
bool sorted;
int * popArray;
};
CPP
#include "population.h"
//Default Constructor
population::population(void)
{
}
//Constructor to intialize the population object
population::population(int arr[], int s)
{
//Store s into a variable
arraySize = s;
//Declare popArray as a Dynamic array
popArray = new int[arraySize];
//Copy the passed array into the popArray
for ( int i=0; i < s; i++)
{
popArray[i] = arr[i];
};
}
//Constructor for deep copying purposes
population::population (const population & p)
{
}
population::~population(void)
{
}
int population::size(void)
{
//Return size of the array, which is the amount of population in the array.
return arraySize;
}
int population::sum(void)
{
//Variable to hold sum of the array
int sumArray = 0;
//Add all the contents of the array into one variable
for ( int i = 0; i < arraySize; i++)
{
sumArray += popArray[i];
}
//Return the sum of the array
return sumArray;
}
float population::mean(void)
{
//Variable to hold sum and the mean of the array
int sumArray = 0;
float meanArray;
//Add all the contents of the array into one variable
for ( int i=0; i < arraySize; i++)
{
sumArray += popArray[i];
}
//Sum of the array divided by number of contents in the array (Average)
meanArray = (sumArray / arraySize);
//Returns mean value in type float
return meanArray;
}
float population::median ()
{
return 1;
}
float population::stddev()
{
return 1;
}
int population::*mode(int & i)
{
return
}
With a prototype like that, I'm guessing that he wants you to new an array to be returned:
int *population::mode(int & i)
{
// compute the number of modal values you need to return
i = /* whatever the size of the return array will be */;
int * ret = new int[i];
// fill in ret
return ret;
}
Try:
int foo(int arrayBar[])
or
int foo(int* arrayBar)
or
int* foo(int arrayBar[])
If those don't work, make sure your pointer is at the beginning of the array.
Source: Return array in a function
Related
My problem:
I have the following piece of code that is a wrapper for 2D square matrices in order to transpose them and print them. I cannot understand why we can write this:
arrayNN(T DATA[N][N]){
n = N;
data = DATA; }
In particular this line of code:data = DATA;.
My thoughts:
As far as i know, in C/C++ you cannot give the values of a matrix to another matrix. For example this piece of code doesn't work, no matter how we write the definition of b:
double array[3][3] = { {11,12,13},{21,22,23},{31,32,33}};
//only one definition
//double **b;
//double *b[3]
double b[3][3];
b = array;
Code: It works.
#include <iostream>
using namespace std;
template <typename T, size_t N>
class arrayNN {
private:
int n;
T (*data)[N]; # a vector of N elements of pointers to datatype T = 2d matrix
public:
arrayNN(): n(N), data(NULL) {};
arrayNN(T DATA[N][N]){
n = N;
data = DATA;
}
void print(ostream &out){
for(int i = 0;i<N;i++){
for(int j=0;j<N; j++){
cout << data[i][j] << '\t';
}
cout << endl;
}
}
void transpose(){
for(int i = 0;i<N;i++){
for(int j=0;j<i; j++){
T temp = data[i][j];
data[i][j] = data[j][i] ;
data[j][i] = temp;
}
}
}
};
int main(){
double array[3][3] = { {11,12,13},{21,22,23},{31,32,33}};
arrayNN<double,3> A(array);
A.print(cout);
A.transpose();
A.print(cout);
return 0;
}
T (*data)[N]; # a vector of N elements of pointers to datatype T = 2d matrix
No, data is not a vector or an array. Instead it is a pointer to an array of size N with elements of type T.
This means that when you wrote data = DATA; you're actually assigning the pointer DATA to the pointer data. Note that the function parameter DATA is a pointer and not an array. You can refer to What is array to pointer decay? for seeing why DATA is a pointer.
I want to do something like:
int a[][]; // I know this code won't work, its to demonstrate what I want to do
void func(int n, int m){
a = int[n][m];
}
that is, initialise a global array whose size depends on function input. If this array was local, it would be a trivial case, but I don't know how to do this in the case shown above. Any help would be very useful!
You can create a matrix with std::vector:
std::vector<std::vector<int>> a;
void func(int n, int m) {
a.resize(n);
for(int i = 0; i < n; i++) {
a[i].resize(m);
}
}
Then you can access elements in the same way you do with int a[][]:
a[i][j] = number;
One way to achieve this is to encapsulate a flat std::vector in a Matrix class and use math to get an element with row and column as in this example:
template<typename T>
class Matrix {
private:
vector<T> vec;
//...
public:
T& get_value(size_t const row, size_t const col) {
return vec[row * col_count + col];
}
};
you can try this
int ** a; // is a pointer of two dimension
void func(int n, int m){
a = new int*[n]; //dynamic allocation global pointer a
for(int i = 0; i < n; i++)
a[i] = new int[m]();
}
I've been tasked with creating a C++ class called Polynomial that applies different mathematical formulas to the Polynomial. I was given 4 separate bits of code that are a requirement to use along with the rest of my program and I don't quite understand how I am suppose go about using these wrappers throughout my functions. Such as in my print function and accessing the polynomial hidden multiple layers in.
Premade 1:
#ifndef __GUARDED_ARRAY_H__
#define __GUARDED_ARRAY_H__
using namespace std;
typedef int ItemType;
const unsigned MAX_LENGTH = 500;
//
// GuardedArray
// - A wrapper class for C++ arrays to make array access safe.
// Specifically, initialization is guaranteed, and assertions are
// in place to detect array index out of bound errors in array member
// accesses.
//
class GuardedArray {
public:
// Purpose: Initializes array elements to zeros
GuardedArray();
// Purpose: Initializes all array elements to a given value
GuardedArray(ItemType x);
// Purpose: Read array element at index i
ItemType read(unsigned i) const;
// Purpose: Write x into array element at index i.
void write(unsigned i, ItemType x);
private:
ItemType array[MAX_LENGTH];
};
#endif
Premade 2:
#include <cassert>
#include "polynomial.h"
#include "guarded_array.h"
#include "managed_array.h"
GuardedArray::GuardedArray() {
for (unsigned i = 0; i < MAX_LENGTH; i++)
array[i] = 0;
}
GuardedArray::GuardedArray(ItemType x) {
for (unsigned i = 0; i < MAX_LENGTH; i++)
array[i] = x;
}
ItemType GuardedArray::read(unsigned i) const {
assert(i < MAX_LENGTH);
return array[i];
}
void GuardedArray::write(unsigned i, ItemType x) {
assert(i < MAX_LENGTH);
array[i] = x;
}
Premade 3:
#ifndef __MANAGED_ARRAY_H__
#define __MANAGED_ARRAY_H__
#include "guarded_array.h"
using namespace std;
//
// ManagedArray
// - A wrapper class for C++ arrays to facilitate insertion and removal of
// array elements.
// - Every instance of ManagedArray has a size that can be increased
// until the maximum capacity MAX_LENGTH is reached.
//
class ManagedArray {
public:
// Purpose: Initializes array to have zero size.
ManagedArray();
// Purpose: Initializes array to a given size. All array elements
ManagedArray(unsigned N);
// Purpose: Initializes array to a given size. All array elements
// are initialized to x.
ManagedArray(unsigned N, ItemType x);
// Purpose: Return the current size of the array.
unsigned size() const;
// Purpose: Read array element at index i
ItemType read(unsigned i) const;
// Purpose: Write x into array element at index i.
void write(unsigned i, ItemType x);
// Purpose: Insert an element into the array.
void insert(unsigned i, ItemType x);
// Purpose: Remove an element from the array.
void remove(unsigned i);
private:
unsigned count;
GuardedArray array;
};
#endif
Premade 4:
#include <cassert>
#include "polynomial.h"
#include "guarded_array.h"
#include "managed_array.h"
ManagedArray::ManagedArray() : array() {
count = 0;
}
ManagedArray::ManagedArray(unsigned N) : array() {
assert(N <= MAX_LENGTH);
count = N;
}
ManagedArray::ManagedArray(unsigned N, ItemType x) : array(x) {
assert(N <= MAX_LENGTH);
count = N;
}
unsigned ManagedArray::size() const {
return count;
}
ItemType ManagedArray::read(unsigned i) const {
assert(i < count);
return array.read(i);
}
void ManagedArray::write(unsigned i, ItemType x) {
assert(i < count);
array.write(i, x);
}
void ManagedArray::insert(unsigned i, ItemType x) {
assert(i <= count && count < MAX_LENGTH);
for (unsigned j = count; j > i; j--)
array.write(j, array.read(j - 1));
array.write(i, x);
count++;
}
void ManagedArray::remove(unsigned i) {
assert(i < count && count > 0);
for (unsigned j = i; j < count - 1; j++)
array.write(j, array.read(j + 1));
count--;
}
And this here is my own code that must be altered to accommodate for the above code:
#include "polynomial.h"
using namespace std;
int main()
{
Polynomial poly1;
poly1.print();
/* Calculate all of these:
The zero polynomial.
The degree of the zero polynomial.
The value of the zero polynomial when x = 1.
The polynomial P(x) = -1 + 3x^2 - 2x^5.
The degree of P(x).
The value of P(1) and P(-2).
The polynomial Q(x) = 1 + x^3 + 2x^5.
The polynomial P(x) +Q(x).
The polynomial P(x) - Q(x).
The polynomial 4P(x).
The polynomial x^2Q(x).
The polynomial P(x)Q(x).
*/
system("pause");
return 0;
}
Header:
#ifndef POLYNOMIAL_H
#define POLYNOMIAL_H
#include <iostream>
#include <cassert>
#include <iomanip>
#include "managed_array.h"
using namespace std;
//
// Polynomial class
//
//Purpose- To hold and calculate specific polynomial equations
//
//Parameter(s)-
// -None OR
// -An array of coefficients and the size of the array OR
// -An instance of Polynomial to copy into a new instance
//Precondition(s)- In the array/array size constructor the last element of the array must be non-zero
//
//Returns- N/A
//
//Side Effect- Holds all functions required to intialize, hold, and calculate specific polynomial equations
//
//
class Polynomial
{
private:
ManagedArray polynomial;
public:
Polynomial(); //Default constructor
/*
second constructor takes an integer array and an integer array size as arguments, and initializes the target Polynomial
instance with coefficients identical to the elements of the array
A precondition for this operation is that the last element of the array must be non-zero, or else the array size is zero.
*/
Polynomial(int array[], const unsigned int size);
/*
A third constructor expects a Polynomial instance as its sole argument, and initializes the target Polynomial
instance with coefficients identical to those in the argument Polynomial.
*/
//Polynomial();
//Purpose- Apply the Polynomial function to an integer argument.That is, compute the value of the Polynomial for a given value of x.
void evaluate();
//Purpose- An arithmetic addition operation that adds one instance of Polynomial to another.
void add(const Polynomial& poly2);
//Purpose- An arithmetic subtraction operation that subtracts one instance of Polynomial by another.
void subtract();
//Purpose- An arithmetic multiplication operation that multiplies one instance of Polynomial by another.
void multiply();
//Purpose- An arithmetic multiplication operation that multiplies an instance of Polynomial by an integer.
//void multiply();
//Purpose- An arithmetic multiplication operation that multiplies an instance of Polynomial by a polynomial of the form x^k for some non-negative integer k
void raiseDegree();
//Purpose- A Boolean operation that compares two instances of Polynomial to determine if they are identical.
bool equal();
//Purpose- Get the degree of a Polynomial instance.
int getDegree();
//Purpose- Retrieve the coefficient of the term x^k in a Polynomial instance, given a non-negative integer k.
int getCoefficient();
//Purpose- Print a Polynomial instance in a user-friendly format.
void print() const;
//The polynomial (-3 + 4x - 7x^3) should be printed in the following format.- 3 + 4 x - 7 x^3
};
#endif
cpp:
#include "polynomial.h"
#include "managed_array.h"
#include "guarded_array.h"
unsigned int i;
Polynomial::Polynomial()
{
ManagedArray();
GuardedArray();
}
Polynomial::Polynomial(int array[], const unsigned int size)
{
ManagedArray(size);
for (i = 0; i < size; i++)
{
int temp = array[i];
GuardedArray(temp);
}
}
//Polynomial::Polynomial()
//{
//
//}
void Polynomial::evaluate()
{
}
void Polynomial::add(const Polynomial& poly2)
{
}
void Polynomial::subtract()
{
}
void Polynomial::multiply()
{
}
//void Polynomial::multiply()
//{
//
//}
void Polynomial::raiseDegree()
{
}
bool Polynomial::equal()
{
return false;
}
int Polynomial::getDegree()
{
return -1;
}
int Polynomial::getCoefficient()
{
return -1;
}
void Polynomial::print() const
{
}
You only need to deal with data member polynomial in class Polynomial, which represents the coefficients of the polynomial.
For example, polynomial.read(2) should return the coefficient of the term x^2
To get you started, in polynomial.cpp
Polynomial::Polynomial()
:polynomial() {}
Polynomial::Polynomial(int array[], const int size)
:polynomial(size)
{
for (int i = 0; i < size; ++i)
polynomial.write(i, array[i]);
}
double Polynomial::evaluate(double x) const
{
double sum = 0;
for (int i = 0; i < polynomial.size(); ++i)
sum += polynomial.read(i) * pow(x, i);
return sum;
}
I'm trying to pass an array into my function calls for build_max_heap and max_heapify so I can modify the array after each call, but I receive an error saying "candidate function not viable: no known conversion from 'int [9]' to 'int *&'for 1st argument."
#include <iostream>
#include <string>
using namespace std;
void build_max_heap(int*& array, int size);
void max_heapify(int*& array, int size, int index);
void build_max_heap(int*& array, int size)
{
for(int i = size/2; i>=0; i--)
{
max_heapify(array, i);
}
}
void max_heapify(int*& array, int size, int index)
{
int leftChild = 2*index+1;
int rightChild = 2*index+2;
int largest;
int heap_size = size;
if( leftChild <= heap_size && array[leftChild] > array[index])
largest = leftChild;
else
largest = index;
if(rightChild <= heap_size && array[rightChild] > array[largest])
largest = rightChild;
if(largest != index) {
int tempArray = array[index];
array[index] = array[largest];
array[largest] = tempArray;
max_heapify(array, heap_size, largest);
}
}
int main()
{
int array[]={5,3,17,10,84,19,6,22,9};
int size = sizeof(array)/sizeof(array[0]);
build_max_heap(array, size);
return 0;
}
int array[]={5,3,17,10,84,19,6,22,9};
While array can be decayed to a pointer int* to be passed as a function argument, it the pointer cannot be passed as a "non-const reference" int*&, because it is immutable (it is a constant address). You could have passed it as a const reference like this:
void max_heapify(int* const& array, int size, int index)
// ^^^^^^
However, this doesn't make much sense, you can simply pass the pointer by value (a copy of the address of the array), which results in the same: the variable at the caller wont be changed. The usual use case of const& parameters is to pass objects that are expensive to copy, such as std::string. This does not apply to pointers; making a copy of a pointer is as cheap as copying any basic variable.
You should change your functions to take the pointer by value:
void build_max_heap(int* array, int size)
void max_heapify(int* array, int size, int index)
also, correct the call to max_heapify inside build_max_heap, give it the correct number of arguments:
void build_max_heap(int* array, int size)
{
for(int i = size/2; i>=0; i--)
{
max_heapify(array, size, i); // <-- 3 arguments
}
}
I'm trying to implement a dynamic array and here is my function for increasing the capacity
int* changeCapacity(int *arr, int length, int newCapacity) {
int *newArr = new int[newCapacity];
if(length > newCapacity){
return 0;
} else {
for(int i = 0; i < length; i++){
newArr[i] = arr[i];
}
delete[] arr;
arr = newArr;
return arr;
}
}
This is the error i get:
speicher(2465,0x7fff7cfc2310) malloc: * error for object 0x7f9742403910: pointer being freed was not allocated
* set a breakpoint in malloc_error_break to debug
i'm calling it like this:
int* addElement(int *arr, int& length, int& capacity, int val){
if(length >= capacity){
capacity = capacity * 2;
changeCapacity(arr, length, capacity);
arr[length] = val;
length += 1;
return arr;
}else{
arr[length] = val;
length += 1;
return arr;
}
}
I assume that your problem must come from two things IMO :
First:
changeCapacity(arr, length, capacity);
arr[length] = val;
Here you doesn't get the new arr value (returned by changeCapacity()).
So your function addElement() will return Wrong pointer and on your next addElement() that will do free memory corruption.
Why do you have to get the new arr value?
You do the same as here
a = 1;
changeVar(a);
// value of a here?
int changeVar(int a)
{
a = 5;
return (a);
}
How will be the value of a? 1 because the argument of changeVar is a local variable.
Second:
You give a NULL value on your addElement() function.
Right now you are changing the address of arr, in which you have to pass the pointer by reference. Do this:
int* changeCapacity(int *&arr, int length, int newCapacity)
This is somewhat a guess based on the error message, but you have shown:
int* addElement(int *arr, int& length, int& capacity, int val)
{ //...
changeCapacity(arr, length, capacity);
//...
}
which calls:
int* changeCapacity(int *arr, int length, int newCapacity)
{ //...
delete[] arr;
//...
}
However, the original source of the arr argument to addElement() is unknown given the code you have posted so far. Are you by chance doing something like this:
foo()
{ int array[N];
//...
addElement(array, ...);
//...
}
or maybe calling addElement() with a global array variable? In either of those cases, the original array is not allocated via a new[] to match the delete[], and this would appear to be what the runtime library is complaining about. The value of the pointer stated in the error message tends to make me think it was allocated on the stack initially.
Of course the other issues, like not capturing the return value of changeCapacity() and/or addElement(), and the possibility that changeCapacity() might return a NULL pointer are still valid as well, and should be fixed.
Here is a better way of doing it. Everything is well explained in the comments for anyone who wants to learn:
#include <iostream>
using namespace std;
int* changeCapacity(int *arr, int length, int newCapacity);
int* addElement(int *arr, int& length, int& capacity, int val);
int main(){
int length = 0; // no inital elements in array
int capacity = 1; // initial capacity is one
int* arr = new int[capacity]; // allocating space for values
int* temp; // pointer for storing temporary values
/* loop for adding elements to the array */
for(int i=0;i<21;i++){
temp = addElement(arr,length,capacity,i); // adding an element to the array
if(temp == NULL) { // checks if execution was successful
cout<< "NULL returned...\n Exiting Now...";
return 0; // exits the program on failure
}
arr = temp; // changing the value of arr
}
/* loop for printing the array */
for(int i=0;i<length;i++){
cout<<arr[i]<<" ";
}
return 0;
}
/* function for increasing the capacity of array */
int* changeCapacity(int *arr, int length, int newCapacity) {
int *newArr = new int[newCapacity]; // definging a new array
if(length > newCapacity){ // checking if the length of the array is valid
cout<< "invalid length of array\n";
return NULL;
} else {
/* loop for transferring values to the new array */
for(int i = 0; i < length; i++){
newArr[i] = arr[i];
}
delete[] arr; // deleting the old array (clears the memory of the old array)
// arr = newArr; removed as this is not needed
return newArr; // returns the new array
}
}
/* function for adding a new element to the array */
int* addElement(int *arr, int& length, int& capacity, int val){
if(length >= capacity){ // checks if the array has space for storing the given value or not
capacity = capacity * 2; // doubles the capacity of the array
int* temp = changeCapacity(arr, length, capacity); // changes the size of the array to the new one
if(temp == NULL){ // checking if a null was returned
cout<< "Failed to change capacity\n";
return NULL; // returning NULL
}
arr = temp; // the value of arr was not changed in your code (problem corrected)
arr[length] = val; // stores the value in the array
length += 1; // increasing the number of element count of the array
return arr; // returns the new array
}else{
arr[length] = val; // stores the value in the array
length += 1; // increasing the number of element count of the array
return arr; // returns the new array
}
}