I am working on an assignment which must pass pointers for all function
parameters. No global variables are allowed except global constants.
I'm to create an array of "bids" in main and fill it with readBids() function. This works, but I am then supposed to pass it to a function to bubble sort it. My program breaks once my sortBids function is called. I'm learning pointers now and I can't see what I am doing wrong. The Call Stack gives Project4.exe!main()Line32, which points to sortBids(bidArray, numBids);
Any help and an explanation would be very appreciated.
#include <iostream>
#include <string>
using namespace std;
string* readProductName();
int* readNumBids();
double* readBids(string,int);
void sortBids(double*, int*);
void averageBid();
void maxBid();
void totalBid();
void printReport();
int main(){
string* productName;
int* numBids;
productName = readProductName();
numBids = readNumBids();
double* bidArray = readBids(*productName, *numBids);
sortBids(bidArray, numBids);
cout << *productName << " " << *numBids << endl;
for (int i = 0; i < *numBids; i++){
cout << bidArray[i] << endl;
}
system("PAUSE");
delete productName;
delete numBids;
delete bidArray;
return 0;
}
string* readProductName(){
string* productName = new string;
cout << "\n Please enter a product name\n";
cin >> *productName;
return productName;
}
int* readNumBids(){
int* numBids = new int;
cout << "\n Please enter the number of bids\n";
cin >> *numBids;
return numBids;
}
double* readBids(string productName, int numBids){
int* size = new int;
size = &numBids;
string* productNamePtr = new string;
productNamePtr = &productName;
double *bidArray;
bidArray = new double[*size];
cout << "\nHow many bids for the " << *productNamePtr << endl;
for (int i = 0; i < *size; i++){
cout << "Please enter bid #" << i + 1 << endl;
cin >> bidArray[i];
if (bidArray[i] <= 0){
cout << "\nPlease enter an amount larger than 0\n";
i--;
}
}
return bidArray;
}
void sortBids(double* array, int *size){
bool* swap = bool{ false };
double* temp = new double;
do
{
*swap = false;
for (int count = 0; count < *size - 1; count++)
{
if (array[count] > array[count + 1])
{
*temp = array[count];
array[count] = array[count + 1];
array[count + 1] = *temp;
*swap = true;
}
}
} while (*swap);
}
Problem:
You intialise swap to 0. As swap is a pointer to bool, you have a null pointer.
You later dereference this pointer without ever having it point to a valid bool object:
*swap = true;
Tha is UB and this is why you get an access violation !
Solution
Either you define this variable as plain object bool swap = false; and use swap everywhere. Or you initialize it correctly bool *swap = new bool{false}; and you use *swap everywhere.
Miscellaneous advice:
Attention: bidArray is allocated with new[], so you have to delete[] it or risk undefined behaviour !
In pointer definitions, take the habit of puting the star next to the variable and not to the type. Why ? Because optically it is confusing:
bool* a,b; // defines a pointer to bool a, but a PLAIN BOOL b !
bool *a,b; // invites otpically to right interpretation by human reader
Related
My program is supposed to iterate through an array for as many times as there are hours using only a pointer.
for (int i = 0; i < totalHours; i++)
{
cout << " " << i + 1;
while (ptrSvr <= last)
{
rand_set(ptrSvr);
print(ptrSvr);
ptrSvr++;
}
cout << endl;
}
return 0;
With this being the function for rand_set
void rand_set(int* &ps)
{
*ps = rand() % 10;
}
And this being the function for print.
void print(int* ps)
{
cout << " " << *ps << " ";
}
Once this iterates though, I don't understand how to set the pointer back to the first address in the array so that when i increases, it will print a new row starting at the beginning. Currently, it will only print one row. There's also a catch - I can only use the given pointer to access the array. I cannot use array indices.
Additionally, the highest number randomly generated must be stored in a highestAttempts pointer and when printed, must have a * next to it. This functionality must be included in the rand_set function. I've only gotten it to print a * next to all of them, or it gets printed on the first random number, and on each one if they increase.
Thanks for any advice in advance. I am in a 200 level c++ class, so this should be as simple as possible.
Variables are declared and initialized like so.
void initialize(int ts, int* &ps, int* &pt,
int* &l, int* &ha)
{
for (int i = 0; i < ts; i++)
{
ps[i] = 0;
pt[i] = 0;
l = &ps[i];
}
ha = NULL;
srand(time(NULL));
}
...
// Pointer declarations
int *ptrSvr; // Po
int *ptrTotal; // Po
int *last; // Po
int *highestAttempts; // Po
// Variable declarations
int totalServers; // Va
int totalHours; // Va
int total; // Va
// Prompt user for number of serv
// totalServers and totalHours
cout << "Enter the number of web
cin >> totalServers;
cout << "Enter the number of hour
cin >> totalHours;
// Declares arrays for ptrSvr and
// of total servers
ptrSvr = new int[totalServers];
ptrTotal = new int[totalServers];
if you have something like
int arr [] = {};
then
ptrSvr = arr;
after while loop would reset it. otherwise you have to store the very first value of ptrSvr and reset it after while loop exits
Hello I'm having this issue with my C++ problem I'm working on.
Here is the code
Cell.h
#ifndef CELL_H
#define CELL_H
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
class Cell
{
private:
int level;
int row;
int column;
//declares a variable called ptrFunction_array which is an array of 3 function pointers.
typedef void (*ptrFunction[])(void);
static void function1()
{
cout << "I'm function 1";
}
static void function2()
{
cout << "I'm function 2";
}
static void function3()
{
cout << "I'm function 3";
}
public:
Cell(int currentLevel, int currentRow, int currentColumn)
{
level = currentLevel;
row = currentRow;
column = currentColumn;
ptrFunction = new *fArray[3];
fArray[0] = function1();
fArray[1] = function2();
fArray[2] = function3();
}
virtual ~Cell();
void tick()
{
int randomNumber = rand() % 3;
cout << "Cell(" << level << ", " << row << ", " << column << ") ";
fArray[randomNumber];
}
};
#endif // CELL_H
Main.cpp
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include "Cell.h"
using namespace std;
Cell ****myArray;
int main()
{
int level = 0;
int row = 0;
int column = 0;
char userInput = 'y';
srand (time(NULL));
do
{
cout << "Please input the amount of levels: ";
cin >> level;
cout << "Please input the amount of rows: ";
cin >> row;
cout << "Please input the amount of columns: ";
cin >> column;
cout << endl;
myArray = new Cell *** [level];
// Set random number to the elements of the array
for (int currentLevel = 0; currentLevel < level; currentLevel++)
{
myArray [currentLevel] = new Cell ** [row];
for (int currentRow = 0; currentRow < row; currentRow++)
{
myArray [currentLevel][currentRow] = new Cell * [column];
for (int currentColumn = 0; currentColumn < column; currentColumn++)
{
myArray [currentLevel][currentRow][currentColumn] = new Cell (currentLevel, currentRow, currentColumn);
myArray [currentLevel][currentRow][currentColumn] -> tick();
cout << " ";
}
cout << endl;
}
cout << endl;
}
cout << "Do you want to try again? (y / n) ";
cin >> userInput;
cout << endl;
if ((userInput == 'y') || (userInput == 'Y'))
{
for (int currentLevel = 0; currentLevel < level; currentLevel++)
{
for (int currentRow = 0; currentRow < row; currentRow++)
{
for (int currentColumn = 0; currentColumn < column; currentColumn++)
{
delete[] myArray[currentLevel][currentRow][currentColumn];
}
delete[] myArray[currentLevel][currentRow];
}
delete[] myArray[currentLevel];
}
delete[] myArray;
myArray = NULL;
}
}while (userInput != 'n');
return 0;
}
I notice that my fArray isn't inside the scope. the Line ptrFunction = new *fArray[3]; is where my error is. I've recently started learning C++ so I'm in the process of trying to understand why my typedef void (*ptrFunction[])(void); isn't correctly initializing the fArrayfor my program. The goal of my program is to be able to create a 3 dimensional array and be able to point to the Cell Objects and be able to track the location x,y,z.
Why does an error like this happen?
I'm going to ignore the four star pointer for now and stick to what's giving OP the most immediate grief.
A quick walk-through:
Cell(int currentLevel, int currentRow, int currentColumn)
{
level = currentLevel;
row = currentRow;
column = currentColumn;
Not bad to here. But...
ptrFunction = new *fArray[3];
This says assign to the variable ptrFunction, which must already exist and doesn't, a newly allocated array of 3 fArrays. The problem here is ptrFunction has been defined as a type, not a variable. fArray is not a type.
fArray[0] = function1();
fArray[1] = function2();
fArray[2] = function3();
Use fArray as a variable, making what's gone wrong here somewhat clear.
}
Cell needs to look a bit more like this, but not exactly. More on that later.
Cell(int currentLevel, int currentRow, int currentColumn)
{
level = currentLevel;
row = currentRow;
column = currentColumn;
ptrFunction * fArray = new ptrFunction[3];
Now fArray is a variable that points to one or more objects of type ptrFunction (but the definition of ptrFunction is somewhat broken), and points fArray at three ptrFunctions. Technically it points at the first of three ptrFunctions.
fArray[0] = function1();
fArray[1] = function2();
fArray[2] = function3();
}
Now we have an fArray, but it is a local variable and it only exists between the curly braces of Cell's constructor. When the constructor exists, the pointer goes away. The memory allocated does not and is lost. Without fArray pointing to it, you can't easily find it to use or delete it. fArray needs wider scope so that A) the memory isn't lost, and B) so that tick and other members of Cell can see it.
class Cell
{
private:
ptrFunction * fArray;
int level;
and in the constructor:
Cell(int currentLevel, int currentRow, int currentColumn)
{
level = currentLevel;
row = currentRow;
column = currentColumn;
fArray = new ptrFunction[3];
That fixes the can't find fArray.
My recommendation is to get one Cell working and then take a stab at getting a 1 dimensional array of Cells working. When you have one dimension, then try two. You might find that's all you need.
Edit
Forgot to mention this: Function pointers to members functions are an absolute expletive deleted to get right. Here is a page on common pitfalls and how to avoid them.
And here is how we avoid this smurf in the here and now of Modern C++: std::bind and std::function. The tutorials at the bottom of the linked document pages probably describe how to use them for simple cases better than I can.
My output for the call to the temporary array size wont correctly output. It resizes as according, but I can't get the MAX to display the new value of the new array. My error is within the Resize function within the class.
#include <iostream>
#include <vector>
#include <string>
#include <math.h>
#include <ctime>
using namespace std;
class VectorClass {
private:
int * Vector;//This will be our resizeable array
int Size; //Keep track of vector current size
int MAX=10;
int growth = 5;
int num;
int Resize(int growth, int MAX);
public:
VectorClass(int growth, int Size);
~VectorClass();
int AddItem(int num);
void RemoveItem();
void Print(void);
};
VectorClass::VectorClass(int growth, int Size)
{
Size = 10;
growth = 5;
Vector = new int[Size];
}
VectorClass::~VectorClass()
{
cout << "Destructor was called." << endl;
}
//Will insert num into the vector at the current open position
int VectorClass::AddItem(int num)
{
Vector[Size] = num;
Size++; //Indicate that there isnt as much free space
if (Size == MAX)
{
Resize(Size, MAX);
}
Print();
return num;
}
//Get rid of the most recently added item
void VectorClass::RemoveItem()
{
Size--; //Tricks the vector into one fewer elements in it it currently does
Print();
}
int VectorClass::Resize(int growth, int MAX)
{
cout << "Array is full! Resizing the Array!" << endl;
//Step 1: make a copy
int * temp = new int[MAX]; //Make a new array, same size as exiting array
//loop that copies the original into the copy
for (int i = 0; i<MAX; i++)
{
temp[i] = Vector[i];
}
//Step 2: Delete the original
delete[] Vector; //Deletes all elements in the array Vector from the Heap
//Step 3: Make a bigger vector
Vector = new int[MAX + growth];
//Step 4: Reverse the copy and record the size change
for (int i = 0; i<MAX; i++)
{
Vector[i] = temp[i];
}
MAX = MAX + growth;
//Step 5: Delete the copy
delete[] temp;
cout << "Resize was called.\n" << endl;
return MAX;
}
void VectorClass::Print()
{
cout << "*******************************************************" << endl;
for (int i = 0; i< Size; i++)
{
cout << Vector[i] << endl;
}
cout << "Size = " << Size << "\tMAX = " << MAX << "\t Growth = " << growth << endl << endl;
cout << "*******************************************************" << endl;
}
int main(void)
{
VectorClass V(5,10);
for (int i = 0; i <= 4; i++)
{
int x = rand();
V.AddItem(x);
}
//Print the Vector #1
V.Print();
//Delete 2 Items
V.RemoveItem();
V.RemoveItem();
//Add 9 random Numbers
for (int i = 0; i <= 8; i++)
{
int x = rand();
V.AddItem(x);
}
//Print the Vector
V.Print();
system("pause");
return 0;
}
Several things are wrong with you code. The first one, probably not the one you care about most, is that you never free the memory. You should do it in your destructor, or even better use a std::unique_ptr to handle your memory.
Now, i believe you are yourself confused about your own variables. I see that you possess a variable member named num that you never use. Even worse, you have a parameter in AddItem with the same name. Are you sure it does what you want? The same is true for growth. I would advise you to name your member variable differently, so that you know what they are quickly. I prefixe them with "m_" for example, but you can do as you wish.
You do not need to declare your function parameters inside your class. Only in the function prototype.
Then, in your AddItem function, you use your variable Size to determine where to add the new element, but you initialize your array with it too, which means that not only you do not add your elements at the beginning of your array, you try to write them in memory you do not own!
I could continue for a long time. I am sorry but it only appears to me that you do not know C++ at all. You should go learn the basics again, and maybe start with an easier project to begin your C++ learning.
Good luck :-)
I'm in the process of teaching myself C++ and am currently learning about dynamically allocating memory. Here's the code that I'm currently working with:
#include <iostream>
using namespace std;
int *memAdd(int* dyn_Point, int *lenPoint){
int *new_Dyn_Point = new int[*lenPoint * 2];
*lenPoint = *lenPoint * 2;
for(int i = 0; i < *lenPoint; i++){
new_Dyn_Point[i] = dyn_Point[i];
}
delete lenPoint;
delete[] dyn_Point;
return new_Dyn_Point;
}
int main(){
int len = 2;
int *lenPoint = &len;
int current = 0;
int val;
int *dyn_Point = new int[len];
cout << "Input a value for point 1: ";
cin >> val;
dyn_Point[current] = val;
while(val > 0){
current++;
cout << "Input a value for point " << current+1 <<" (0 to exit): ";
cin >> val;
if(current+1 == len){
*dyn_Point = *memAdd(dyn_Point, lenPoint);
cout << len;
}
dyn_Point[current] = val;
}
for(int i = 0; i < len; i++){
cout << &dyn_Point[i] << "\n";
cout << dyn_Point[i] << "\n\n";
}
delete[] dyn_Point;
}
My Question: When adding more memory does it have to increment by a certain value?
Whenever I start with a value in my "len" variable that's not 2 my program will crash either as soon as I try and allocate more memory or after more memory has been allocated and even more has to be added a second time.
Is this how it's supposed to be or am I missing something entirely here?
Your while loop need a break
while() {
//do your steps
break;
}
In function memAdd following changes required :
// *lenPoint = *lenPoint * 2;
// above line need to be commented else it will trouble the loop condition by causing over flow:
for(int i = 0; i < (*lenPoint-1); i++){
// for loop is corrected to resolve the over flow
Below delete is unnecessary since you didn't allocate memory
using this variable
// delete lenPoint;
For your question: When adding more memory does it have to increment by a certain value?
There is no hard and hard fast rule on this regard. std::vector<> double its size( memory allocation) whenever it is needed more memory. It is slightly different than your approach. You are doubling memory before reaching the allocated upper limit.
**Edit**
Compiled full code as OPs request
#include <iostream>
using namespace std;
int *memAdd(int* dyn_Point, int *lenPoint){
int *new_Dyn_Point = new int[*lenPoint * 2];
// *lenPoint = *lenPoint * 2;
for(int i = 0; i < (*lenPoint-1); i++){
new_Dyn_Point[i] = dyn_Point[i];
}
//delete lenPoint;
delete[] dyn_Point;
return new_Dyn_Point;
}
int main(){
int len = 2;
int *lenPoint = &len;
int current = 0;
int val;
int *dyn_Point = new int[len];
cout << "Input a value for point 1: ";
cin >> val;
dyn_Point[current] = val;
while(val > 0){
current++;
cout << "Input a value for point " << current+1 <<" (0 to exit): ";
cin >> val;
if(current+1 == len){
*dyn_Point = *memAdd(dyn_Point, lenPoint);
cout << len<<"\n";
}
dyn_Point[current] = val;
break;
}
for(int i = 0; i < len; i++){
cout << dyn_Point[i] << "\n";
cout << &dyn_Point[i] << "\n\n";
}
delete[] dyn_Point;
}
"My Question: When adding more memory does it have to increment by a certain value?"
Of course you have to manage your memory allocations using a design like this.
In particular you should obey the Rule of Three (Five), and to copy all of the existing elements, when reallocating memory to increase to the necessary amount.
The much better choice than doing it all yourself (which is likely to be error prone), is to use a
std::vector<int> dyn_point;
and/or alike in your class.
Memory management is taken care of in the container implementations, and you don't need to bother about it.
#include <iostream>
using namespace std;
int getDegree()
{
int degree;
cout << "Enter degree of polynomial" << endl;
cin >> degree;
return degree;
}
int* getPoly(int degree)
{
cout << "Enter coefficients in order of power of x. e.g. for 2 + x + 3x^2, enter 2 then 1 then 3" << endl;
int coeff [degree +1];
for (int i = 0; i <= degree; i++)
{
cin >> coeff[i];
}
return coeff;
}
int* polyder(int p[], int degree)
{
int dp[degree];
for(int i = 0; i < degree; i++)
{
dp[i] = p[i+1] * (i+1);
}
return dp;
}
int main(int argc, const char * argv[])
{
int degree = getDegree();
int p = *getPoly(degree);
int dp = *polyder(&p, degree);
for(int i = 0; i < degree +1; i++)
cout << " " << p[i] << " x^" << i;
cout << endl;
for(int i = 0; i < degree +1; i++)
cout << " " << dp[i] << " x^" << i;
cout << endl;
return 0;
}
I am getting an error during the print statements.
I am not worried about the math involved, just how to pass the arrays between functions/methods.
Can anyone find why this is not working?
I am new to C++, used to Java.
Can anyone find why this is not working?
In C++ variables are destroyed when the scope in which they were declared ends. You return an address of a variable that doesn't exist when the function ends:
int* getPoly(int degree)
{
int coeff [degree +1];
// ...
return coeff;
}
If you wish the variable still exists after the function ends, you have to allocate it using new:
int* getPoly(int degree)
{
int *coeff = new int[degree +1];
// ...
return coeff;
}
And, at the end of your main function (or wherever you don't need the array anymore), call delete[] to deallocate the memory:
int *p = getPoly(degree);
delete[] p;
The Array name is essentially a pointer to the first element of the array (as you can see in the code above, I've declared p as a pointer to int), so you pass them to other functions just by providing their name:
int* polyder(int p[], int degree){/*do something here*/}
// <-- some other code
int *p = getPoly(degree);
int* returnedArray = polyder(p,degree);
First of all, the line
int coeff [degree +1];
is not a valid C++ statement unless 'degree' is a constant, even through some compilers may allow it.
Even if some compiler allowed it, the space for coeff is allocated from the stack and will be invalid after the function returns. Hence, the line
return coeff;
returns an memory location that will be invalid at its usage.
In order to return valid memory function, replace the line
int coeff [degree +1];
by
int* coeff = new int[degree];
You don't need degree+1 items in the array.
Similar changes are needed in the function polyder.
The thing to remember about arrays in C++ is that unlike Java, they are not objects (at least in the way they are in Java). They're simply pointers to a block of allocated memory, and the [] operator simply automatically does the math to move the pointer to the correct location.
When passing arrays between functions, you're basically just passing a pointer. Unless you want to get into some highly complicated and likely too much for your use case code, you should always pass the size of the array along with it to ensure that your indexes always stay in bounds.
And as the other answer points out, you need to ensure that the life cycle of the array lasts as long as you need it to. Simply returning a pointer to an object doesn't keep it alive like returning a reference does in Java.