2017-11-18 85 views
0

对于我正在实施散列映射的任务。我的valueOf()函数在main中返回垃圾,即使它找到了键的值并将其输出到函数中。我找到了两种可能的解决方案,但都不适合我的情况。C++模板基于指针的变量导致垃圾被返回,除非在之前存储和输出

类概述:

的HashTable

template <typename V> 
class HashTable { 
private: 
    string m_key; 
    V m_value; 
... 

MyStringMap

template <typename V> 
class MyStringMap : public AbstractStringMap<V> { 
private: 
    HashTable<V> * m_table; 
    int m_maxSize; 
    int m_currSize; 
    string EMPTY_KEY; 
    string TOMB_KEY; 
... 

而问题功能(这是在MyStringMap):

const V& valueOf(const string& key) const throw (Oops) { 
    int home; 
    int pos = home = hash(key); 

    // stops at found key (for success) or empty key (for failed) 
    for (int i = 1; (key != m_table[pos].getKey()) && (EMPTY_KEY != m_table[pos].getKey()); i++) 
     pos = (home + probe(key, i)) % m_maxSize; 

    // check found pos and return accordingly 
    if (key == m_table[pos].getKey()) { 
     return m_table[pos].getValue(); 
    } 
    else 
     throw Oops("Key Not Found!!"); 
} 

上面的return m_table[pos].getValue();部分在main中输出时会返回垃圾,导致程序崩溃。但是,函数中有cout << "FOUND [" << m_table[pos].getKey() << "] [" << m_table[pos].getValue() << "]" << endl;(返回之前)会显示正确的值。

我运行它主要的方式是:

try { 
    cout << "Person1? " << thelist.valueOf("Person1") << endl; 
    cout << "Person2? " << thelist.valueOf("Person2") << endl; 
} catch (Oops e) { 
    cout << e.getMsg() << endl; 
} 

两个解决方案,我发现,但不适合有:

  • 追加c_str()到的结束主要功能,例如:cout << "Person1? " << thelist.valueOf("Person1").c_str() << endl;。由于我无法编辑main(如赋值指令),所以我不能使用它。
  • 返回一个变量,而不是直接的价值,并具有输出它在那里,例如:

V found = m_table[pos].getValue(); cout << "FOUND [" << m_table[pos].getKey() << "] [" << found << "]" << endl;

无论出于何种原因,这使得回报显示正确的非垃圾值。但是,它是一个拙劣的解决方案,我不希望额外的输出。


任何帮助,将不胜感激。我会在需要的地方澄清,因为我确信这可能没有意义。

+0

[mcve],请。山姆的回答下面有正确的可能性,但为什么猜测? – user4581301

回答

0

我猜你的getValue()方法返回一个V对象。该对象在堆栈上创建。然后您返回对该对象的引用。然后堆栈被你计算机中其他的东西覆盖,你会得到垃圾。这也解释了为什么返回一个对象的原理:它被分配在内存空间中并且不被覆盖。

总之,您正在返回对堆栈中对象的引用。你不能这样做,因为你不知道在稍后阅读时该地址会是什么。

+0

那么正确返回值的方法是什么?将它分配给一个变量并返回该变量仍然会导致垃圾,除非我将.c_str()追加到main中的返回值。 – huhn