Note that there are some explanatory texts on larger screens.

plurals
  1. POC++ unordered_map with char* as key
    primarykey
    data
    text
    <p>I feel exhausted when trying to use the container <code>unordered_map</code> with <code>char*</code> as the key (on Windows, I am using VS 2010). I know that I have to define my own compare function for <code>char*</code>, which inherits from <code>binary_function</code>. The following is a sample program.</p> <pre><code>#include&lt;unordered_map&gt; #include &lt;iostream&gt; #include &lt;string&gt; using namespace std; template &lt;class _Tp&gt; struct my_equal_to : public binary_function&lt;_Tp, _Tp, bool&gt; { bool operator()(const _Tp&amp; __x, const _Tp&amp; __y) const { return strcmp( __x, __y ) == 0; } }; typedef unordered_map&lt;char*, unsigned int, ::std::tr1::hash&lt;char*&gt;, my_equal_to&lt;char*&gt; &gt; my_unordered_map; //typedef unordered_map&lt;string, unsigned int &gt; my_unordered_map; my_unordered_map location_map; int main(){ char a[10] = "ab"; location_map.insert(my_unordered_map::value_type(a, 10)); char b[10] = "abc"; location_map.insert(my_unordered_map::value_type(b, 20)); char c[10] = "abc"; location_map.insert(my_unordered_map::value_type(c, 20)); printf("map size: %d\n", location_map.size()); my_unordered_map::iterator it; if ((it = location_map.find("abc")) != location_map.end()) { printf("found!\n"); } return 0; } </code></pre> <p>I insert the same C string <code>abc</code> twice and look it up. The second insertion should fail and there will be only one <code>abc</code> in the unordered_map. However, the output size is 3. It seems that the compare function does not work properly here.</p> <p>Moreover, I get another strange result about the <code>find</code> function, by running the program for many times, the finding result even changes! Sometimes the string <code>abc</code> is found, while the other times <code>abc</code> is not found!</p> <p>Could anyone help me on this? Your help is very much appreciated!</p> <p>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++</p> <p>Edit: After defining a hash function for <code>char*</code> by my own, the program works properly. The full program code is listed below. Thank you all.</p> <pre><code>#include&lt;unordered_map&gt; #include &lt;iostream&gt; using namespace std; template &lt;class _Tp&gt; struct my_equal_to : public binary_function&lt;_Tp, _Tp, bool&gt; { bool operator()(const _Tp&amp; __x, const _Tp&amp; __y) const { return strcmp( __x, __y ) == 0; } }; struct Hash_Func{ //BKDR hash algorithm int operator()(char * str)const { int seed = 131;//31 131 1313 13131131313 etc// int hash = 0; while(*str) { hash = (hash * seed) + (*str); str ++; } return hash &amp; (0x7FFFFFFF); } }; typedef unordered_map&lt;char*, unsigned int, Hash_Func, my_equal_to&lt;char*&gt; &gt; my_unordered_map; int main(){ my_unordered_map location_map; char a[10] = "ab"; location_map.insert(my_unordered_map::value_type(a, 10)); char b[10] = "abc"; location_map.insert(my_unordered_map::value_type(b, 20)); char c[10] = "abc"; location_map.insert(my_unordered_map::value_type(c, 20)); printf("map size: %d\n", location_map.size()); my_unordered_map::iterator it; if ((it = location_map.find("abc")) != location_map.end()) { printf("found!\n"); } return 0; } </code></pre> <p><strong>Note: Using <code>char</code>* as the key type for an unordered_map or other STL containers may be dangerous, a safe way (seems to be the only way) is: in the main function, <code>new</code> or <code>malloc</code> a block (e.g. an array of c strings) on heap and fill it with c strings. Insert these c strings into unordered_map. The allocated block of memory is freed at the end of of main function (by <code>delete</code> or <code>free</code>).</strong></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload