Stuck on C++ Segmentation fault while working with String

Stuck on C++ Segmentation fault while working with String

here is the full code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <string>

template <typename K, typename V>
class TableItems {
public:
    K key;
    V value;
    int hash = -1;
};

template <typename K, typename V>
class HashTable {
public:
    TableItems<K, V> *table;
    long long capacity = 8;
    long long size = 0;
    HashTable() {
        this->table = (TableItems<K, V>*)malloc(this->capacity * sizeof(TableItems<K, V>));
        for (int i = 0; i < this->capacity; i++) {
            this->table[i] = TableItems<K, V>();
        }
    }
};

int main()
{
    //HashTable<int, int> table;

    HashTable<std::string, std::string> table;
    std::cout << "Hello, Table\n";
    return 0;
}


i wonder it works fine with int data type i try

//HashTable<int, int> table;

but it throw error Segmentation fault on strings

 
HashTable<std::string, std::string> table;


EDIT:
Error seems on these lines:

1
2
3
        for (int i = 0; i < this->capacity; i++) {
            this->table[i] = TableItems<K, V>();
        }


But as i am creating pointer of class object why behaving different in string!


Please help me to figure out why this happens and fixes.
Thanks
Last edited on
> this->table = (TableItems<K, V>*)malloc(this->capacity * sizeof(TableItems<K, V>));
Do NOT use malloc in a C++ program.
malloc doesn't call constructors, new does.

You 'get away with it' with PoD types like int, because it basically doesn't matter.
But complex types (anything with it's own constructor), you lose.

So do this.
table = new TableItems<K, V>[capacity];

Also, you don't need this-> in front of everything unless you have some kind of name clash to resolve.
TableItems does not have a constructor, so line 21 calls the implicitly defined default constructor, which is the same as a constructor with an empty body and an empty initialiser list. So table is an array filled with uninitialised items. If you initialise them later, the first initialisation is a waste of CPU time.

Both of the classes are not RAII compliant: why not have a std::vector<TableItems*> , then you won't have that problem? If TableItems had a constructor that initialised K and V, you could use emplace_back to fill the vector. Otherwise, if using new, provide destructors.

Line 20 has implicit conversions (long long , int), why not use std::size_t ?
Last edited on
Thanks for both answers.

@TheIdeasMan
The reason is that i have implement has table from starch and i am interested to understand things how it work under the hood.

https://github.com/lablnet/Data_Structure/tree/main/HashTable
Here is an article by Bjarne, no less, about RAII:

https://www.stroustrup.com/3rd_safe.pdf
Thanks
Topic archived. No new replies allowed.