1

I have a class called Dictionary that contains a key-value pair, a pointer to this key-value pair, and an int that holds the size of the dictionary.

template<typename K, typename V>
class Dictionary
{
public:

V& operator[](K key);

private:

struct KeyValue
{
    K key;
    V value;
}; //the key-value pair struct

KeyValue* array; //pointer to an array of items (the key-value pairs)

int size; //size of the dictionary (i.e. the array size)
};

I am trying to overload the [] operator for this class and when I do so, I get a segmentation fault error

template<typename K, typename V>
V& Dictionary<K,V>::operator[](K key){
  for (size_t i = 0; i < size; i++) {
    if (key == array[i].key) {
      return array[i].value;
    }
  }
  array[size].value = 0;
  size++;
  return array[size-1].value;
}

I beleive that the seg fault is occuring in this line

array[size].value = 0;

However, I don't know exactly why it's happening. Any help is greatly appreciated. Thanks!

2
  • Sounds like you are reimplementing std::map (badly). Why would you do that rather than just using std::map? Commented Nov 16, 2019 at 15:11
  • 1
    Just because the program crashes on this line doesn't mean that's where the problem is. C++ does not work this way. The problem can be anywhere in your program, which is why stackoverflow.com's help center instructs you to provide a minimal reproducible example, otherwise it is unlikely that anyone will be able to help you. See How to Ask for mroe information. Commented Nov 16, 2019 at 15:12

1 Answer 1

5

When an array in C and C++ has N elements, the valid indexes are: 0, 1, 2, ... N-1. In contrast N is not a valid index: it is past the end of the array.

In this particular case, the last element of array is array[size - 1]:

array[0]         // first element
array[1]         // second element
// ...
array[size - 2]  // second-to-last element
array[size - 1]  // last element

array[size]      // error: beyond the last element

Using array[size] is accessing beyond the end of the array and results in a segmentation fault.

In the bigger picture, if you need to add elements to an array and you are out of space in the array, you would need to allocate a new array with larger size, and move (or copy) elements from the old array to the new array.

This is "reallocating", and this is what std::vector<T> does when it grows beyond its current capacity.

You may want to replace your use of a dynamic array with an std::vector<KeyValue>. That would let the std::vector take care of these operations.

Sign up to request clarification or add additional context in comments.

4 Comments

This assumes that array was actually alocated for size elements, and there aren't any additional reserve capacity (like what std::vector does). There's nothing in the question to support this assumption. The question is unanswerable without a minimal reproducible example.
I have also tried incrementing size first and then calling array[size-1] however this also results in a segmentation fault
@SamVarshavchik, that is correct, I made that assumption based on the comment in the questioner's code: //size of the dictionary (i.e. the array size)
@ZacharyRudebeck, the segmentation fault is expected in that case: the array index is equal to the size of the array, which means it is an invalid index. Just incrementing the variable size does not increase the size of the array. You need to allocate a new array with a larger size, or use std::vector which takes care of this for you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.