Jump to content
  • Advertisement
Sign in to follow this  
Zdman

Deleting triple pointer, double pointers it's just not working

This topic is 4970 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

i don't know if anyone will be able to help but i keep getting a debug error of DAMAGE: after Normal block (#71) at 0x00491E20. If I press ignore it will continue. When I get to delete [] models, I get a Debug assertion Failed...Expresion: _CrtIsValidHeapPointer(pUserData)----after this i get an unhandled expression and it crashes. I don't know what is causing this. I think I'm doing it right. Here's that section of code. char buffer[255]; char nLoop; int num_dealers; char** dealers; char*** models; int* num_of_models_per_dealer; double** prices; double* averages; .......... for(int i = 0; i < num_dealers; i++) { delete [] dealers; }; delete [] dealers; for(i=0; i < num_dealers; i++) { for(int j=0; j < num_of_models_per_dealer; i++) { delete [] models[j]; }; delete [] models; }; delete [] models; for(i=0; i < num_dealers; i++) { delete [] prices; }; delete [] prices; delete [] averages; delete [] num_of_models_per_dealer;

Share this post


Link to post
Share on other sites
Advertisement
better? [smile]
i believe for the delete [] dealers
you can just do delete dealers, unless dealers points to other pointers.
either that or your syntax is wrong....

char buffer[255];
char nLoop;
int num_dealers;
char** dealers;
char*** models;
int* num_of_models_per_dealer;
double** prices;
double* averages;

..........

for(int i = 0; i < num_dealers; i++)
{
delete [] dealers;
}
delete [] dealers;
for(i=0; i < num_dealers; i++)
{
for(int j=0; j < num_of_models_per_dealer; i++)
{
delete [] models[j];
};
delete [] models;
}
delete [] models;
for(i=0; i < num_dealers; i++)
{
delete [] prices;
}
delete [] prices;
delete [] averages;
delete [] num_of_models_per_dealer;

Share this post


Link to post
Share on other sites
I would suggest setting your pointers to NULL after clearing them. This way, if you accidently use or delete them afterwards, you will get a much more trackable crash.

Another thing I have found useful in the past is to do this:

Dealer* pDealer = dealers;
delete pDealer;
dealers = NULL;

instead of:

delete dealers;

Not a big deal, but it helps me make sure I know what I am deleting. It also helps when code changes; if the type is explicit, it helps remind me that I need to change that type. Delete will just deallocate whatever at that address, regardless of the object type.

You can try scattering _CrtCheckMemory() calls around to track down the source. Take a look at the compiler documentation for this function. This may trap the problem earlier and help you find out which deletion is causing issues.

A few other items to consider:
Are you sure all of these pointers are assigned to valid objects?
Are you sure all of your array indices are in bounds?
Are you sure all of these objects are allocated on the stack?
Have you walked through it in the debugger to make sure all of your assumptions are correct?

Share this post


Link to post
Share on other sites
That's a neat idea with allocating a pointer. But I don't think it'll help too much. I have stepped through it and have tried some of the things above. To me it seem like it has deleted if if I press ignore and everyone of them do it so it's something in all of them. They all hold valid objects because I've used them in the body of the program and it all works. The pointers you see are on the stack but everything they contain are created are not. I don't know what _CrtCheckMemory() is so if you could explain. My code isn't very long so I'm going to post it here.

#include <iostream>
#include <iomanip>
#include <string>
#include <math.h>
#include <stdio.h>
#include <ctype.h>

using namespace std;

//Constants

//Function Declarations
int readNumDealers( );
//Reads the number of dealers from the user. You may call the function atoi( ) provided in the standard library within this function. You will have to include stdlib.h to use this function. The function atoi( ) converts a passed string to an integer and returns the integer, or 0 if the conversion cannot be made. The function prototype for atoi( ) is: int atoi( const char *nPtr).

char** readDealers( int num_of_dealers);
//Reads the names of the dealers from the user. Returns the names via a double pointer.
//Use new memory to allocate an array of pointers, each of which points to a dealer's name. Use the num_of_dealers parameter to specify the size of the array of pointers. Allocate an array of characters for each dealer and store that pointer in the array of pointers.

char*** readModels(int num_of_dealers, char**dealer_names, int *num_of_models_per_dealer);
//Reads the names of each model sold for a specified dealer. This function will need to prompt for the number of models sold for a specific
//dealer. This number of models will be maintained in the num_of_models_per_dealer array. Use the dealer_names to make your prompt
//more user friendly


double **readPrices( int no_of_dealers, char **dealers, char ***models, int *num_of_models_per_dealer);
//This function allows the user to enter the price for each model (pertaining to a specific dealership) and stores the price of that model in the
//appropriate location in the dynamically allocated double** described above. You will need to dynamically allocate the double** in this
//function. Use the dealers and models arrays to make your prompt more user friendly:


double *calcAvg(int no_of_dealers, double **prices, int *num_of_models_per_dealer);
//This function calculates the average price of all models that a dealer sells. The average price is stored in the average array described above.



void displayInfo(int no_of_dealers, int *num_of_models_per_dealer, char **dealers, char ***models, double** prices, double *avg);
//Displays all information pertaining to dealerships and their models . Example Output:


//Functions
int main()
{
char buffer[255];
char nLoop;
int num_dealers;
char** dealers;
char*** models;
int* num_of_models_per_dealer;
double** prices;
double* averages;

do{
num_dealers = readNumDealers();
dealers = readDealers(num_dealers);
num_of_models_per_dealer = new int[num_dealers];
models = readModels(num_dealers, dealers, num_of_models_per_dealer);
prices = readPrices(num_dealers, dealers, models, num_of_models_per_dealer);
averages = calcAvg(num_dealers, prices, num_of_models_per_dealer);
displayInfo(num_dealers, num_of_models_per_dealer, dealers, models, prices, averages);

for(int i = 0; i < num_dealers; i++)
{
delete [] dealers;
};
delete [] dealers;
for(i = 0; i < num_dealers; i++)
{
for(int j = 0; j < num_of_models_per_dealer; i++)
{
delete []models[j];
};
delete [] models;
};
delete [] models;
for(i = 0; i < num_dealers; i++)
{
delete [] prices;
};
delete [] prices;
delete [] averages;
delete [] num_of_models_per_dealer;
//Loop
cout << "Would you like to enter more Dealerships?(Y or N) ";
cin.getline(buffer, sizeof(buffer));
nLoop = buffer[0];
}while(nLoop == 'Y' || nLoop == 'y');

return 0;
}


//Reads the number of dealers from the user. You may call the function atoi( ) provided in the standard library within this function. You will have to include stdlib.h to use this function. The function atoi( ) converts a passed string to an integer and returns the integer, or 0 if the conversion cannot be made. The function prototype for atoi( ) is: int atoi( const char *nPtr).
int readNumDealers( )
{
char buffer[255];

cout << "How many dealers are there? ";
cin.getline(buffer, sizeof(buffer));

return(atoi(buffer));
}

//Reads the names of the dealers from the user. Returns the names via a double pointer.
//Use new memory to allocate an array of pointers, each of which points to a dealer's name. Use the num_of_dealers parameter to specify the size of the array of pointers. Allocate an array of characters for each dealer and store that pointer in the array of pointers.
char** readDealers(int num_of_dealers)
{
char buffer[255];
char** dealers;

dealers = new char*[num_of_dealers];

for(int i = 0; i < num_of_dealers; i++)
{
cout << "Please enter the name of dealer #" << i + 1 << ": ";
cin.getline(buffer, sizeof(buffer));
dealers = new char[strlen(buffer)];
strcpy(dealers, buffer);
};

return dealers;
}

//Reads the names of each model sold for a specified dealer. This function will need to prompt for the number of models sold for a specific
//dealer. This number of models will be maintained in the num_of_models_per_dealer array. Use the dealer_names to make your prompt
//more user friendly
char*** readModels(int num_of_dealers, char**dealer_names, int *num_of_models_per_dealer)
{
char buffer[255];
char*** models;

models = new char**[num_of_dealers];

for(int i = 0; i < num_of_dealers; i++)
{
cout << "Please enter the number of models for " << dealer_names << ": ";
cin.getline(buffer, sizeof(buffer));
num_of_models_per_dealer = atoi(buffer);
models = new char*[num_of_models_per_dealer];
for(int j = 0; j < num_of_models_per_dealer; j++)
{
cout << " Please enter the name of model #" << j + 1 << ": ";
cin.getline(buffer, sizeof(buffer));
models[j] = new char[strlen(buffer)];
strcpy(models[j], buffer);
};
};

return models;
}

//This function allows the user to enter the price for each model (pertaining to a specific dealership) and stores the price of that model in the
//appropriate location in the dynamically allocated double** described above. You will need to dynamically allocate the double** in this
//function. Use the dealers and models arrays to make your prompt more user friendly:
double **readPrices(int no_of_dealers, char **dealers, char ***models, int *num_of_models_per_dealer)
{
char buffer[255];
double** prices;

prices = new double*[no_of_dealers];

for(int i = 0; i < no_of_dealers; i++)
{
prices = new double[num_of_models_per_dealer];
for(int j = 0; j < num_of_models_per_dealer; j++)
{
cout << "Please enter the price for " << dealers << "'s " << models[j] << ": ";
cin.getline(buffer, sizeof(buffer));
prices[j] = atoi(buffer);
};
cout << endl;
};

return prices;
}

//This function calculates the average price of all models that a dealer sells. The average price is stored in the average array described above.
double *calcAvg(int no_of_dealers, double **prices, int *num_of_models_per_dealer)
{
double* averages;

averages = new double[no_of_dealers];

for(int i = 0; i < no_of_dealers; i++)
{
averages = 0;
for(int j = 0; j < num_of_models_per_dealer; j++)
{
averages += prices[j];
};
averages /= num_of_models_per_dealer;
};

return averages;
}

//Displays all information pertaining to dealerships and their models.
void displayInfo(int no_of_dealers, int *num_of_models_per_dealer, char **dealers, char ***models, double** prices, double *avg)
{
cout << setprecision(2) << fixed;
for(int i = 0; i < no_of_dealers; i++)
{
cout << "Information on dealership #" << i + 1 << endl;
cout << " Dealership name: " << dealers << endl;
for(int j = 0; j < num_of_models_per_dealer; j++)
{
cout << " " << models[j] << ": " << prices[j] << endl;
};
cout << "........................" << endl;
cout << " Average price of all models is " << avg << endl;
cout << endl;
}
}

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
goodness, a triple pointer? I rarely use a double pointer anymore. Don't get so messed up in this pointer jungle and put things in containers and structs. Not sure about your scenario, but it helps to contain things better.

struct modelStruct {
model *model_data;
char *name;
//etc, you would only do this if it does help to give metadata
}

even more helpful is containers, like STL's

std::vector models;

Anyway, you might already know all this, but you shouldn't be touching raw pointers so much unless it's a core part of the system, and it doesn't really look like it.

Share this post


Link to post
Share on other sites
A DAMAGE error is *always* due to overwriting an array bounds.
First off, put asserts in around every array access to ensure that you are not going past the end (or start) of the array.

If you ever find yourself using three *'s in a row (***) then there's a good chance you're doing something wrong.
Second, I highly recommend you learn how to use references and const-references.

Third, there is your copy-and-paste bug in main:
      for(int j = 0; j < num_of_models_per_dealer; i++)
It should be j++.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!