Hello all,

I am trying to write the constructor for the HashTable class, so it will create an array when a HashTable object is created. With the code below, I am getting the errors:

error C2466: cannot allocate an array of constant size 0
error C2133: 'arrayTest' : unknown size

Is it a problem to create an array in the constructor?

I have also tried calling a function to create the array, but get the same errors.

#include "utility.h"
#include "Key.h"
#include "HashTable.h"

using namespace std;

int main() 
{
    HashTable<Key> hTable1(97);
	
	
	cout << "hello world" << endl;

}
#ifndef HASHTABLE_H
#define HASHTABLE_H

#include "utility.h"
#include "Key.h"
#include <list>

using namespace std;

template <class Key>
class HashTable
{
public:
    HashTable(int array_size); //constructor
    //Post: A hash table of size array_size been created.



};

template <class Key>
HashTable<Key>::HashTable(int array_size)
{
	int size = array_size;
	int arrayTest[size];
	cout << "size: " << size << endl;

	cout << "made it " << endl;



}








#endif //HASHTABLE_H

Dani AI

Generated

The MSVC errors you saw come from trying to make a fixed C-style array with a runtime size inside the constructor. and were on the right track: you need storage that can be sized at runtime and owned by the HashTable object, not an automatic local array that vanishes when the constructor returns. Also avoid putting using namespace std; in a header — it can pollute every translation unit that includes your header.

A simple, safe option that meets an "array of lists" requirement while handling lifetime and copying correctly is to use std::vector of lists:

template<class Key>
class HashTable {
    std::vector<std::list<Key>> buckets;
    std::size_t bucket_count;

public:
    explicit HashTable(std::size_t n) : buckets(n), bucket_count(n) {}
    // buckets[i] is an empty std::list<Key> ready for use
};

If your assignment forbids std::vector, prefer a smart pointer over raw new[] to manage lifetime and avoid leaks:

template<class Key>
class HashTable {
    std::unique_ptr<std::list<Key>[]> buckets;
    std::size_t bucket_count;

public:
    explicit HashTable(std::size_t n)
      : buckets(n ? new std::list<Key>[n] : nullptr), bucket_count(n) {}
    HashTable(const HashTable&) = delete;          // or implement deep copy
    HashTable& operator=(const HashTable&) = delete;
};

Additional practical notes: use std::size_t for sizes, keep template definitions visible to the compiler (templates are usually defined in headers), and if you use raw pointers implement the destructor/copy/move properly (rule of three/five) or explicitly delete copy operations. For background on the containers and smart pointers, see the cppreference pages for std::vector and std::unique_ptr (vector, unique_ptr).

Recommended Answers

All 8 Replies

Looks like it works if I use a vector. The assignment does not mention vectors.

For hash tables, I am supposed to use an array of lists. Do I have the right idea with the code above?

Hello all,

I am trying to write the constructor for the HashTable class, so it will create an array when a HashTable object is created. With the code below, I am getting the errors:

error C2466: cannot allocate an array of constant size 0
error C2133: 'arrayTest' : unknown size

Is it a problem to create an array in the constructor?

I have also tried calling a function to create the array, but get the same errors.

#include "utility.h"
#include "Key.h"
#include "HashTable.h"

using namespace std;

int main() 
{
    HashTable<Key> hTable1(97);
	
	
	cout << "hello world" << endl;

}
#ifndef HASHTABLE_H
#define HASHTABLE_H

#include "utility.h"
#include "Key.h"
#include <list>

using namespace std;

template <class Key>
class HashTable
{
public:
    HashTable(int array_size); //constructor
    //Post: A hash table of size array_size been created.



};

template <class Key>
HashTable<Key>::HashTable(int array_size)
{
	int size = array_size;
	int arrayTest[size];
	cout << "size: " << size << endl;

	cout << "made it " << endl;



}








#endif //HASHTABLE_H

In answer to your first question:
You can't instantiate a regular array with a variable, because the size has to be known at compile-time so that the correct amount of stack memory can be allocated for the program.

If your assignment does not mention vectors, maybe they meant dynamic arrays?

In answer to your first question:
You can't instantiate a regular array with a variable, because the size has to be known at compile-time so that the correct amount of stack memory can be allocated for the program.

If your assignment does not mention vectors, maybe they meant dynamic arrays?

Isn't a vector a dynamic array?

Try this:

const array_size 100

Isn't a vector a dynamic array?

Yes and no. A std::vector is a templated container-class which acts similarly to a C-style array, and will dynamically increase the amount of memory it needs without your direct intervention.

The other responder probably meant using a pointer and dynamically-allocated memory to be used as a C-style array, and either way do youreally want the array declared locally within your constructor?

template <class Key>
class HashTable
{
private:
    int array_size;
    int *array_vals;

public:
    HashTable(int array_size); //constructor
...
};

template <class Key>
HashTable<Key>::HashTable(int req_array_size) :
    array_size(0), array_vals(NULL)
{
    if (req_array_size > 0) {
        array_vals = new int [req_array_size];
        if (array_vals)
            array_size = req_array_size;
    }
    ...
}

"do you really want the array declared locally within your constructor?"

What's the alternative? Calling a method that declares the array? What is the benefit in that?

Um, no. Your constructor -is- a method, albeit a special purpose one, but the same rules hold true. If you declare a new variable within the body of the constructor, then it exists only within that scope (until the constructor returns).

The alternative is as I coded it: declare the array as a member of your class, and -initialize- it in the constructor. Unless, for whatever reason, the array is needed only during the execution of the constructor, and no other method of the class needs to access it. Then you can declare it in the constructor, but still need to do so dynamically:

int array_size=0, *array_test=NULL;
if (size > 0) {
    array_test = new int [size];
    if (array_test)
        array_size = size;
}
...

I see what you're saying. I ended up changed that, because like you said, I needed to use the array elsewhere.

If you have a minute, could you take a look at my response in my "Type Mismatch?" thread?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.