0

Spend the whole afternoon to debug one issue. Completely confused on why I can print the first element from an empty list. It seems this is C++ issue or my program issue. It seems C++ randomly point to local address when I try to access the first element

int main(int argc, char **argv)
 {
         string crc_command = "ls /tmp/jacknotexist";
         list<string> crc_output;
         printf("list begin:%s\n", (*(crc_output.begin())).c_str()); // The result is "ls /tmp/jacknotexist". Why???
         printf("list size:%d\n", crc_output.size()); // It is zero as expected.
}
Jacky Chen
  • 127
  • 1
  • 1
  • 6
  • 2
    Because C++ doesn't hold your hand and tell you off if you don't follow its rules. You don't pay for what you don't use. – chris Jul 26 '14 at 21:20
  • to be honest I get a segmentation fault.. anyway chris is right: accessing out-of-bounds memory is undefined behavior. The standard pattern is to check the bounds and **then** read – Marco A. Jul 26 '14 at 21:23
  • By the way, using `printf` to print the result of `size()` is unsafe. There's a good chance that `%zu` is the right format specifier, but you can't be sure. – chris Jul 26 '14 at 21:25
  • that's the real difference between `[]` and the member function `at()` when dealing with vectors, here the principle is the same, C++ gives you the tools, you are supposed to know better about how things work or should work in memory. – user2485710 Jul 26 '14 at 21:27
  • In C++ I would use std::cout – AxelOmega Jul 26 '14 at 21:31
  • How do you print an element from an empty list. It`s just empty and there is no element to print, because the list basically contains a null reference. Unless you add the string "crc_command" to the list then your list will contain a null reference. – Juniar Jul 26 '14 at 23:10
  • A good compiler in debug mode should generate an error for you, although it doesn't have to. – Neil Kirk Jul 26 '14 at 23:50

1 Answers1

3

The result is "ls /tmp/jacknotexist". Why???

Actually, the result is undefined behavior: even though the list is empty, its begin() function returns some value (which happens to be equal to the value returned by end() function). When you dereference that iterator, it again produces some value. At this point, the behavior is undefined, and a program could crash on any other platform.

Essentially this is the same sort of behavior that one gets when dereferencing an invalid pointer: the program may or may not crash, and it may produce any value at all. In your case, the invalid value happens to coincide with the content of crc_command variable.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523