I've created a class, Category.

#ifndef CATEGORY_H_INCLUDED
#define CATEGORY_H_INCLUDED

#include <string>
using std::string;

enum Type {Integer, Double, Bool, String, Date, Time};

class Category
{
    public:
        Category() : itsType(String) {}
        Category(Type type) : itsType(type) {}
        Category(string name) : itsName(name) {}
        Category(Type type, string name) : itsName(name), itsType(type) {}
        ~Category() {}

        void operator=(const Category& rCat) {itsName = rCat.itsName; itsType = rCat.itsType;}

        const Type& GetType() const {return itsType;}
        const string& GetName() const {return itsName;}

    private:
        string itsName;
        Type itsType;
};

#endif // CATEGORY_H_INCLUDED

Used in main.cpp.

#include <iostream>
using namespace std;

#include "Category.h"

int main()
{
    Category test(String, string("Test"));
    Category* pCat = new Category;
    pCat[0] = test;
    cout << "Name: " << pCat[0].GetName() << endl;
    cout << "Type: " << pCat[0].GetType() << endl;
    delete [] pCat; //Crashes the program
    //delete pCat; //Works fine

    return 0;
}

The problem is indicated in main().
When I use delete [] pCat the program crashes.
When I do the same using delete pCat , it doesn't.
If there's more than 1 Category in the array, the problem doesn't occur...

I've tried doing the same with int, which works fine. I can't seem to figure out why it doesn't work for Category..

Any input is welcome.

The proper use of delete and delete []

int *Num = new int;
int *Array = new int[5];

delete Num; //good
delete [] Num; //Bad -- undefined 
delete [] Array; //good
delete Array; //bad --undefined

As you can see, you have :

Category* pCat = new Category;

Which should follow up with a

delete pCat;

You are using an array notation bracket, i.e [] on pCat, and that
is probably why it lead you to think you should use delete [] pCat,
but in fact, if you know abut pointers, pCat[0] is the same as *pCat.

Also (1) pCat[0].GetType() is the same as (2) (*pCat).GetType and (3) pCat->GetType.
Use the option (3), as it is more clear, that pCat is not an array of a class object and "prettier."

Edited 7 Years Ago by firstPerson: n/a

The proper use of delete and delete []

int *Num = new int;
int *Array = new int[5];

delete Num; //good
delete [] Num; //Bad -- undefined 
delete [] Array; //good
delete Array; //bad --undefined

As you can see, you have :

Category* pCat = new Category;

Which should follow up with a

delete pCat;

You are using an array notation bracket, i.e [] on pCat, and that
is probably why it lead you to think you should use delete [] pCat,
but in fact, if you know abut pointers, pCat[0] is the same as *pCat.

Also (1) pCat[0].GetType() is the same as (2) (*pCat).GetType and (3) pCat->GetType.
Use the option (3), as it is more clear, that pCat is not an array of a class object and "prettier."

I would normally go with option (3). However, I was using the class in a program with a self-written form of Vector, and it kept crashing upon destruction of the object.
I was hoping there was a way around just leaving the [] out, since it means an extra if-condition in the Vector-class...

Guess that's an anwser though, unless there's a specific reason why the deletion goes wrong.

" I was using the class in a program with a self-written form of Vector, and it kept crashing upon destruction of the object."

Mind showing your constructor and destructor?

#define DEFAULTSIZE 0

template <class T>
class Array
{
    public:
        //Public constructor
        Array() {itsSize = DEFAULTSIZE; itsElements = 0;}
        //Copy constructor
        Array(const Array&);
        //Destructor
        ~Array() {if(itsSize > 1) delete [] itsElements; else if(itsSize == 1) delete itsElements;}
        //Previous destructor
        //~Array() {if(itsSize) delete [] itsElements;
    private:
        //Private constructor
        Array(int size) {itsSize = size; itsElements = new T[itsSize];}
        //Private variables
        int itsSize;
        T* itsElements;
};

I modified the destructor to prevent the crashing. The old destructor is commented out under it.

Normally with destructor and constructor,
you should do something like ,

Array(){
  mainArray = new Type[0];
}
~Array(){
  delete [] mainArray;
}

Here is a complete example.

#include <iostream>
#include <string> 
 
using std::cout;
using std::string;
using std::endl;

template<typename Type>
class Array
{
	typedef unsigned int uInt;
private:
	uInt len;
	Type * mainArray;
public:
	Array(){
		mainArray = new Type[0];
		len = 0;
	}
	Array(uInt Sz, Type val){
		mainArray = new Type[Sz];
		len = Sz;
		for(uInt i = 0; i < Sz; i++)
			mainArray[i] = val;
	}
	~Array(){
		//Its able to delete a null pointer, i.e if(len == 0);
		delete [] mainArray; 
	}
	bool isEmpty() {
		return len == 0; 
	}
	uInt Size(){
		return len; 
	}
	bool Print(int col)
	{
		if(!len) 
			return false;

		for(uInt i = 0; i < len; i++) {
			if(i && i % col == 0) 
				cout << endl;			
			cout<<mainArray[i]<<" ";
		}
		
		return true;
	}
	
};

int main()
{  
	Array<int> Numbers;
	Array<float> Numerics(12,10);

	cout<<"Numbers size is : " << Numbers.Size() << endl;
	cout<<"Numerics size is: "<< Numerics.Size() << endl;
	
	if(Numbers.Print(4))
		;
	else cout<<"Nothing to print in Numbers\n";

	cout<<endl;

	if(Numerics.Print(4))
		;
	else cout<<"Nothing to print in Numerics\n";
	
	cout<<"\n\n";


	return 0;
}

Thanks for the info. I'll go and change that..

EDIT:
Seems to still give crashes. If I use delete [] mainArray on my Category class it still crashes

Edited 7 Years Ago by BeyondTheEye: n/a

Same problem as in the first post, without a dynamic array. I've never had it with any other class, so I'd assume Category is the problem, not the Array class.

Figured it out. It appears new Type isn't quite the same as new Type[1]

Yep, if you look closely, you would have seen that on my post.

This question has already been answered. Start a new discussion instead.