|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
|
|
Thread Tools | Rate Thread | Display Modes |
|
|
|
#1
|
||||
|
||||
|
Re: C++ help: Understanding pointers?
Okay so after reading all of this and getting (what I think is) a better understanding of pointers, I attempted my book's chapter's next practice problem:
Quote:
Here's the code I wrote. It has 2 main errors that repeat many times that the compiler picked up and I wouldn't be surprised if there were several more. It looks like a lot, but you'll quickly realize that it's very small, quick, and (hopefully) simple so please don't be put off by its size. So what's wrong with this and how can I fix it? Please ignore the fact that I made it a 3x? 2dimensional array instead of a 3dimensional array. I noticed that towards the end of writing this but that's not the main focus of the exercise so I'll fix that later. Code:
//get 3 user-input values and make a 3dimensional array with those dimensions. Allocate that much memory.
#include <iostream>
using namespace std;
void setValues(int *a, int *b, int *c, int *arrayOne[], int *arrayTwo[], int *arrayThree[]);
void showValues(int *a, int *b, int *c, int *arrayOne[], int *arrayTwo[], int *arrayThree[]);
int main()
{
int firstNumber;
int *p_firstNumber = & firstNumber;
int secondNumber;
int *p_secondNumber = & secondNumber;
int thirdNumber;
int *p_thirdNumber = & thirdNumber;
//get the 3 sizes
cout << "Give me a length, width, and height!\n";
cout << "Length: "; cin >> firstNumber;
cout << "Width: "; cin >> secondNumber;
cout << "Height: "; cin >> thirdNumber;
//create the pointer version of the 3dimensional array
int **p_p_fullArray = new int[3];
int *p_firstArray = new int[firstNumber];
int *p_secondArray = new int[secondNumber];
int *p_thirdArray = new int[thirdNumber];
//set the 3 1dimensional arrays to the full array
p_p_fullArray[0] = & p_firstArray;
p_p_fullArray[1] = & p_secondArray;
p_p_fullArray[2] = & p_thirdArray;
//create normal variables for the 3dimensional array
int firstArray[firstNumber];
int secondArray[secondNumber];
int thirdArray[thirdNumber];
//set the 3 1dimensional pointers to the 3 1dimensional variables
p_firstArray = & firstArray;
p_secondArray = & secondArray;
p_thirdArray = & thirdArray;
//assign something to every cell in the array
setValues(int *p_firstNumber, int *p_secondNumber, int *p_thirdNumber, int *p_firstArray[], int *p_secondArray[], int *p_thirdArray[]);
//show the array (easy way to make sure the program worked)
cout << "\nCool thanks. Here's your array:" << endl;
showValues(int *p_firstNumber, int *p_secondNumber, int *p_thirdNumber, int *p_firstArray[], int *p_secondArray[], int *p_thirdArray[]);
//free the allocated memory and make sure the pointers don't grab on to anything random and cause issues
delete p_p_fullArray;
p_p_fullArray = NULL;
delete p_firstArray;
p_firstArray = NULL;
delete p_secondArray;
p_secondArray = NULL;
delete p_thirdArray;
p_thirdArray = NULL;
delete p_firstNumber;
p_firstNumber = NULL;
delete p_secondNumber;
p_secondNumber = NULL;
delete p_thirdNumber;
p_thirdNumber = NULL;
}
void setValues(int *a, int *b, int *c, int *arrayOne[], int *arrayTwo[], int *arrayThree[])
{
int value = 0;
for (int i = 0; i < a; i++)
{
*arrayOne[i] = value;
++value;
}
for (int j = 0; j < b; j++)
{
*arrayTwo[j] = value;
++value;
}
for (int k = 0; k < c; k++)
{
*arrayThree[k] = value;
++value;
}
}
void showValues(int *a, int *b, int *c, int *arrayOne[], int *arrayTwo[], int *arrayThree[])
{
cout << "first row: ";
for (int i = 0; i < a; i++)
{
cout << arrayOne[i] << " ";
}
cout << "\nsecond row: ";
for (int j = 0; j < b; j++)
{
cout << arrayTwo[j] << " ";
}
cout << "\nthird row: ";
for (int k = 0; k < c; k++)
{
cout << arrayThree[k] << " ";
}
}
|
|
#2
|
||||
|
||||
|
Re: C++ help: Understanding pointers?
|
|
#3
|
||||
|
||||
|
Re: C++ help: Understanding pointers?
You're very close with your code, but you actually need a 3rd level of indirection.
int*** p3Dimensions = new int**[width]; for(int x = 0;x < width; x++) { p3Dimensions[x] = new int*[height]; for(int y = 0;y < height; y++) { p3Dimensions[x][y] = new int[depth]; for(int z = 0;z < depth; z++) { p3Dimensions[x][y][z] = x*y*z; } } } I'm pretty tired from practice day at waterloo, so I'll let you figure out how that works ... if it compiles, which it might not. |
|
#4
|
||||
|
||||
|
Re: C++ help: Understanding pointers?
Quote:
Code:
//get 3 user-input values and make a 3dimensional array with those dimensions. Allocate that much memory.
#include <iostream>
using namespace std;
// See at implementation
void setValues(int *a, int *b, int *c, int arrayOne[], int arrayTwo[], int arrayThree[]); // void setValues(int *a, int *b, int *c, int *arrayOne[], int *arrayTwo[], int *arrayThree[]);
void showValues(int *a, int *b, int *c, int arrayOne[], int arrayTwo[], int arrayThree[]); // void showValues(int *a, int *b, int *c, int *arrayOne[], int *arrayTwo[], int *arrayThree[]);
int main()
{
int firstNumber;
int *p_firstNumber = & firstNumber;
int secondNumber;
int *p_secondNumber = & secondNumber;
int thirdNumber;
int *p_thirdNumber = & thirdNumber;
//get the 3 sizes
cout << "Give me a length, width, and height!\n";
cout << "Length: "; cin >> firstNumber;
cout << "Width: "; cin >> secondNumber;
cout << "Height: "; cin >> thirdNumber;
//create the pointer version of the 3dimensional array
int **p_p_fullArray = new int*[3]; // int **p_p_fullArray = new int[3];
int *p_firstArray = new int[firstNumber];
int *p_secondArray = new int[secondNumber];
int *p_thirdArray = new int[thirdNumber];
//set the 3 1dimensional arrays to the full array
p_p_fullArray[0] = p_firstArray; // p_p_fullArray[0] = & p_firstArray;
p_p_fullArray[1] = p_secondArray; // p_p_fullArray[1] = & p_secondArray;
p_p_fullArray[2] = p_thirdArray; // p_p_fullArray[2] = & p_thirdArray;
// this part is trying to statically allocate an array with a length derived from
// a runtime value (illegal), and then leaks memory because you're removing the arrays
// you allocated using new
/*
//create normal variables for the 3dimensional array
int firstArray[firstNumber];
int secondArray[secondNumber];
int thirdArray[thirdNumber];
//set the 3 1dimensional pointers to the 3 1dimensional variables
p_firstArray = & firstArray;
p_secondArray = & secondArray;
p_thirdArray = & thirdArray;
*/
// functions are called by passing values, not by declaring what types those values are
//assign something to every cell in the array
setValues(p_firstNumber, p_secondNumber, p_thirdNumber, p_firstArray, p_secondArray, p_thirdArray); // setValues(int *p_firstNumber, int *p_secondNumber, int *p_thirdNumber, int *p_firstArray[], int *p_secondArray[], int *p_thirdArray[]);
//show the array (easy way to make sure the program worked)
cout << "\nCool thanks. Here's your array:" << endl;
// same as before
showValues(p_firstNumber, p_secondNumber, p_thirdNumber, p_firstArray, p_secondArray, p_thirdArray); // showValues(int *p_firstNumber, int *p_secondNumber, int *p_thirdNumber, int *p_firstArray[], int *p_secondArray[], int *p_thirdArray[]);
// delete is not enough for arrays. delete normally just calls a destructor and deallocates memory for a single instance.
// If you want to deallocate an array, you should use delete [].
//
// Although setting pointers to NULL when you're done with them is a good idea, if you aren't
// going to use them again (in a situation like, for example, your program ending), there's no point
//free the allocated memory and make sure the pointers don't grab on to anything random and cause issues
delete [] p_p_fullArray; // delete p_p_fullArray;
p_p_fullArray = NULL;
delete [] p_firstArray; // delete p_firstArray;
p_firstArray = NULL;
delete [] p_secondArray; // delete p_secondArray;
p_secondArray = NULL;
delete [] p_thirdArray; // delete p_thirdArray;
p_thirdArray = NULL;
// you tried to delete statically allocated memory. This messes stuff up.
/*
delete p_firstNumber;
p_firstNumber = NULL;
delete p_secondNumber;
p_secondNumber = NULL;
delete p_thirdNumber;
p_thirdNumber = NULL;
*/
}
// a note on parameters: arrays, when used as function parameters, degenerate and become identical
// to pointers. Therefore, you're asking for 3 int**s, which is definitely not what you passed. Pick
// either * or [], whichever better represents how you use it.
void setValues(int *a, int *b, int *c, int arrayOne[], int arrayTwo[], int arrayThree[]) // void setValues(int *a, int *b, int *c, int *arrayOne[], int *arrayTwo[], int *arrayThree[])
{
int value = 0;
// you have to dereference a pointer to be able to use it as a normal value
//
// also, i j and k each go out of scope after each loop, so you don't have to
// choose a different name for each. Name them all i and they'll technically
// be different variables, but will still be called i. Consistency is good, and
// coming up with a new name for the iterator in each loop is pointless.
for (int i = 0; i < *a; i++) // for (int i = 0; i < a; i++)
{
// since you don't pass in an int**, don't use it as one
arrayOne[i] = value; // *arrayOne[i] = value;
++value;
}
for (int j = 0; j < *b; j++) // for (int j = 0; j < b; j++)
{
arrayTwo[j] = value; // *arrayTwo[j] = value;
++value;
}
for (int k = 0; k < *c; k++) // for (int k = 0; k < c; k++)
{
arrayThree[k] = value; // *arrayThree[k] = value;
++value;
}
}
// same as above
void showValues(int *a, int *b, int *c, int arrayOne[], int arrayTwo[], int arrayThree[]) // void showValues(int *a, int *b, int *c, int *arrayOne[], int *arrayTwo[], int *arrayThree[])
{
cout << "first row: ";
// same situation. Dereference, dereference, dereference!
for (int i = 0; i < *a; i++) // for (int i = 0; i < a; i++)
{
cout << arrayOne[i] << " ";
}
cout << "\nsecond row: ";
for (int j = 0; j < *b; j++) // for (int j = 0; j < b; j++)
{
cout << arrayTwo[j] << " ";
}
cout << "\nthird row: ";
for (int k = 0; k < *c; k++) // for (int k = 0; k < c; k++)
{
cout << arrayThree[k] << " ";
}
}
Code:
#include <iostream>
#include <sstream>
using namespace std;
// once created, arr[i][j][k] will be the product i*j*k
int*** makeMultTable(int l,int w,int h) {
if(l <= 0 || w <= 0 || h <= 0)
return NULL;
// allocate top-layer containing array
int*** ret = new int**[l];
for(int i=0;i<l;++i) {
// allocate array to store rows
ret[i] = new int*[w];
for(int j=0;j<w;++j) {
// allocate individual row
ret[i][j] = new int[h];
// set each row element to its value in the multiplication table
for(int k=0;k<h;++k)
ret[i][j][k] = i*j*k;
}
}
return ret;
}
void printTable(int*** table,int l,int w,int h) {
if(!table || l <= 0 || w <= 0 || h <= 0)
return;
// find longest possible int
// used for prettifying the grid
stringstream digitTest;
// if i, j, and k are less than l, w, and h respectively,
// then the largest value of i*j*k is (l-1)*(w-1)*(h-1)
digitTest << (l-1)*(w-1)*(h-1);
// find greatest amount of digits for prettification
int digitLength = digitTest.str().length();
// go by layers because text is only 2 dimensional at best
for(int i=0;i<l;++i) {
cout << "i = " << i << ":" << endl;
for(int j=0;j<w;++j) {
// go through each element in the row
for(int k=0;k<h;++k) {
// reset prettifying stream
digitTest.str("");
// single grid element
digitTest << table[i][j][k];
// prettify the element
while(digitTest.str().length() < digitLength)
digitTest << " ";
// no extra space needed at the end of a row
if(k != h-1)
digitTest << " ";
// output prettified element
cout << digitTest.str();
}
// row done
cout << endl;
}
// layer done
cout << endl;
}
}
void freeMultTable(int*** table,int l,int w,int h) {
if(!table || l <= 0 || w <= 0 || h <= 0)
return;
// delete contents from the inside out
for(int i=0;i<l;++i) {
for(int j=0;j<w;++j)
// delete individual row
delete [] table[i][j];
// delete one layer
delete [] table[i];
}
// delete whole table
delete [] table;
}
int main() {
int l,w,h;
cout << "Length? ";
cin >> l;
cout << "Width? ";
cin >> w;
cout << "Height? ";
cin >> h;
int*** table = makeMultTable(l,w,h);
printTable(table,l,w,h);
freeMultTable(table,l,w,h);
return 0;
}
Code:
#include <iostream>
#include <sstream>
#include <stdexcept>
using namespace std;
class MultTable {
int*** table;
int l,w,h;
public:
MultTable(int l_,int w_,int h_) : l(l_),w(w_),h(h_) {
if(l <= 0 || w <= 0 || h <= 0)
throw runtime_error("Invalid dimensions");
// allocate top-layer containing array
table = new int**[l];
for(int i=0;i<l;++i) {
// allocate array to store rows
table[i] = new int*[w];
for(int j=0;j<w;++j) {
// allocate individual row
table[i][j] = new int[h];
// set each row element to its value in the multiplication table
for(int k=0;k<h;++k)
table[i][j][k] = i*j*k;
}
}
}
~MultTable() {
if(!table || l <= 0 || w <= 0 || h <= 0)
return;
// delete contents from the inside out
for(int i=0;i<l;++i) {
for(int j=0;j<w;++j)
// delete individual row
delete [] table[i][j];
// delete one layer
delete [] table[i];
}
// delete whole table
delete [] table;
}
int get(int i,int j,int k) const {
if(i <= 0 || j <= 0 || k <= 0 ||
i >= l || j >= w || k >= h)
throw runtime_error("Index out of range");
}
string toString() const {
stringstream out;
// find longest possible int
// used for prettifying the grid
stringstream digitTest;
// if i, j, and k are less than l, w, and h respectively,
// then the largest value of i*j*k is (l-1)*(w-1)*(h-1)
digitTest << (l-1)*(w-1)*(h-1);
// find greatest amount of digits for prettification
int digitLength = digitTest.str().length();
// go by layers because text is only 2 dimensional at best
for(int i=0;i<l;++i) {
out << "i = " << i << ":" << endl;
for(int j=0;j<w;++j) {
// go through each element in the row
for(int k=0;k<h;++k) {
// reset prettifying stream
digitTest.str("");
// single grid element
digitTest << table[i][j][k];
// prettify the element
while(digitTest.str().length() < digitLength)
digitTest << " ";
// no extra space needed at the end of a row
if(k != h-1)
digitTest << " ";
// output prettified element
out << digitTest.str();
}
// row done
out << endl;
}
// layer done
out << endl;
}
return out.str();
}
};
ostream& operator<<(ostream& o,const MultTable& multTable) {
return o << multTable.toString();
}
int main() {
int l,w,h;
cout << "Length? ";
cin >> l;
cout << "Width? ";
cin >> w;
cout << "Height? ";
cin >> h;
MultTable table(l,w,h);
cout << table;
return 0;
}
|
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|