-3

Now, I'm reading a file, then checking each line and putting each character into a char[]. However, when I run a for loop and plus i equal to string length, the program developed in Visual Studio 2010 will crash. But, when I developed on my laptop which installed Visual Studio 2012, the final character will be \0.

For example:

while(getline(infile, str)) {
    char buf[1024];
    int index = 0;
    for (int i = 0; i < str.length(); i++) {
        while(str[i] != ',' && str[i] != '\0') {
            buf[index++] = str[i++];
        }
    }
}

It will crash when I use Visual Studio 2010 but success in Visual Studio 2012. Does anyone know the reason? What is the last element of string? Isn't is a \0? Or it's a compiler problem ? If there's anything insufficient, please tell me to add.

CYB
  • 1,106
  • 15
  • 36
  • 1
    You have `i++` twice in there.. guaranteed to cause an index out of bounds error. Is that a typo? – metacubed Jun 04 '14 at 03:37
  • 2
    Why are you using a char array, anyway? And why are you messing with the loop variable inside the loop? That's just asking for bugs. Also, [the spec for this operator changed in C++11](http://en.cppreference.com/w/cpp/string/basic_string/operator_at), which may be related to your problem? – user2357112 Jun 04 '14 at 03:39
  • @metacubed Yes, it's necessary for my condition, because I want to except some characters. – CYB Jun 04 '14 at 03:39
  • Is it deliberate that you never null-terminate `buf`? – user2357112 Jun 04 '14 at 03:40
  • @user2357112 Sorry, I have put a `\0` into `buf` but I didn't write it above. – CYB Jun 04 '14 at 03:42
  • @user2357112 Your answer seems like a plausible explanation - can you confirm that VS 2012 does use the new standard? – metacubed Jun 04 '14 at 03:43
  • @metacubed: It supports some parts of the standard. I don't know whether support for this particular part is in there. – user2357112 Jun 04 '14 at 03:48
  • @user2357112 I use loop inside a loop because I want to scan the string. It works on my VS2012 but not on my VS2010. I'm so confused. – CYB Jun 04 '14 at 03:51
  • Another possibility is that the length of `str` is exceeding the buffer size (1024). – metacubed Jun 04 '14 at 03:51
  • @metacubed In my test, the length is always only around 4 to 10. – CYB Jun 04 '14 at 03:52
  • 1
    @CYB: The outer loop already scans the string. Unless you really like scanning, you don't need to put a scan in your scan so you can scan while you scan. You could just use `if` instead of `while` and not increment `i` inside the loop. – user2357112 Jun 04 '14 at 03:53
  • 1
    @CYB try running your program in Release mode with no optimizations on both VS 2010 and 2012. Debug mode sometimes gives you a safety net which hides overflow errors. – metacubed Jun 04 '14 at 03:53
  • @CYB Also like user2357112 mentioned, just use `if(... == ',' ...) { continue; }` inside the for loop. That will simplify the logic. – metacubed Jun 04 '14 at 03:56
  • There's a very easy solution: just change `&& str[i] != '\0'` in the inner loop to `&& i < str.length()`, to match the outer loop condition. But put this test before the `str[i] != ','` part, so that if it fails the `&&` will short circuit and you won't try to read past the end of the string. – j_random_hacker Jun 04 '14 at 03:57
  • What are you trying to do? Removing any NULL and comma characters that may be present in the string? – Praetorian Jun 04 '14 at 04:03
  • Why not use an iterator instead? – Ignacio Vazquez-Abrams Jun 04 '14 at 04:10
  • This can't be all the code, since you never do anything with `buf`. The problem is probably in the code you didn't show. – Mark Ransom Jun 04 '14 at 04:33

2 Answers2

0

According to this answer will-stdstring-always-be-null-terminated-in-c11 , str[str.length()] will return '\0'. but apparently doesn't hold a '\0' in memory though.

Corrected after comment from Praetorian.

Community
  • 1
  • 1
Indika Pathi
  • 81
  • 1
  • 3
  • No, the NULL character (value initialized CharT) is required to be part of the string's buffer according to 21.4.7.1, otherwise the requirement for `data()` and `c_str()` are violated - both return "a pointer `p` such that `p + i == &operator[](i)` for each `i` in `[0,size()]`" – Praetorian Jun 04 '14 at 04:13
0

As @metacubed mentioned, I use Release mode, and it works.

CYB
  • 1,106
  • 15
  • 36