Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>Using a char pointer as a key like you are above is almost certainly not what you want to do.</strong></p> <p>STL containers deal with stored values, in the case of <code>std::unordered_map&lt;char *, unsigned int, ...&gt;</code>, you are dealing with pointers to c strings, which may not even be around on subsequent insertion/removal checks.</p> <p>Note that your <code>my_unordered_map</code> is a global variable but you are trying to insert local char arrays a, b, and c. What do you expect your comparison function <code>my_equal_to()</code> to <code>strcmp()</code> when the inserted c strings fall out of scope? (You suddenly have keys pointing to random garbage that can be compared to newly inserted future values.)</p> <p>It is important that STL map keys be copyable values that cannot have their meanings changed by external program behavior. <strong>You should almost certainly use <code>std::string</code> or similar for your key values, even if their construction seems wasteful to you at first glance.</strong></p> <p>The following will work exactly as you intend things to work above, and is vastly safer:</p> <pre><code>#include &lt;unordered_map&gt; #include &lt;iostream&gt; #include &lt;string&gt; using namespace std; // STL containers use copy semantics, so don't use pointers for keys!! typedef unordered_map&lt;std::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)); cout &lt;&lt; "map size: " &lt;&lt; location_map.size() &lt;&lt; endl; my_unordered_map::iterator it; if ((it = location_map.find("abc")) != location_map.end()) { cout &lt;&lt; "found \"" &lt;&lt; it-&gt;first &lt;&lt; "\": " &lt;&lt; it-&gt;second &lt;&lt; endl; } return 0; } </code></pre>
    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.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. COThanks, but the reason why I want to use `char*` rather than `std::string` is the performance of the program. An anonymous object of `std::string` will be created each time I insert a character string. And I do not understand why a global `unordered_map` variable will be a problem. Actually the pointers passed to `my_equal_to()` are all virtual addresses in this program, and I do not understand how the inserted c strings fall out of scope. Could you please elaborate on this?
      singulars
    2. CO@Bloodmoon What you have in your fix works but will fail completely in real-use scenarios. The char a[10], b[10], and c[10] arrays are created on the stack and effectively go away once they fall out of scope. To illustrate this, make a void foo() and an int bar(), where foo() does the a/b/c definitions and map inserts. In bar(), make an int x[100] and populate it with values 1 to 100, then add them and return the value. In main(), call foo(), then bar() before looking for the values. It will fail, because you overwrote the same memory values that used to contain the char arrays...
      singulars
    3. CO@Bloodmoon To summarize my longer comment above, your problem is not that the memory holding the character arrays will get unmapped, but that the stack address space holding the characters will be overwritten eventually. The only reason your example worked is that you defined a/b/c in the same function as EVERY map insertion. In fact, you could probably omit what I have about the bar() function, and the first "map size: " printing call will probably nuke the char arrays set in the foo() call...
      singulars
 

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