0

I am defining an array of size 9. but when I access the array index 10 it is not giving any error.

int main() {
   bool* isSeedPos = new bool[9];
   isSeedPos[10] = true;
}

I expected to get a compiler error, because there is no array element isSeedPos[10] in my array.

Why don't I get an error?

Alok Save
  • 202,538
  • 53
  • 430
  • 533
user570593
  • 3,420
  • 12
  • 56
  • 91

13 Answers13

5

It's not a problem.

There is no bound-check in C++ arrays. You are able to access elements beyond the array's limit (but this will usually cause an error).

If you want to use an array, you have to check that you are not out of bounds yourself (you can keep the sizee in a separate variable, as you did).

Of course, a better solution would be to use the standard library containers such as std::vector. With std::vector you can either

  • use the myVector.at(i)method to get the ith element (which will throw an exception if you are out of bounds)
  • use myVector[i] with the same syntax as C-style arrays, but you have to do bound-checking yourself ( e.g. try if (i < myVector.size()) ... before accessing it)

Also note that in your case, std::vector<bool> is a specialized version implemented so that each booltakes only one bit of memory (therefore it uses less memory than an array of bool, which may or may not be what you want).

Louen
  • 3,617
  • 1
  • 29
  • 49
1

No, the compiler is not required to emit a diagnostic for this case. The compiler does not perform bounds checking for you.

It is your responsibility to make sure that you don't write broken code like this, because the compiler will not error on it.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
1

Unlike in other languages like java and python, array access is not bound-checked in C or C++. That makes accessing arrays faster. It is your responsibility to make sure that you stay within bounds.

However, in such a simple case such as this, some compilers can detect the error at compile time.

Also, some tools such as valgrind can help you detect such errors at run time.

Rémi
  • 3,705
  • 1
  • 28
  • 39
1

What compiler/debugger are you using? MSVC++ would complain about it and tell you that you write out of bounds of an array. But it is not required to do it by the standard. It can crash anytime, it causes undefined behaviour.

1

Primitive arrays do not do bounds-checking. If you want bounds-checking, you should use std::vector instead. You are accessing invalid memory after the end of array, and purely by luck it is working.

Graham Borland
  • 60,055
  • 21
  • 138
  • 179
1

Use std::vector instead. Some implementations will do bounds checking in debug mode.

markh44
  • 5,804
  • 5
  • 28
  • 33
1

There is no rule stateing that the memory access is checked in c, plain and simple. When you ask for an array of bool's it might be faster for the Operating system to give you a 16bit og 32bit array, instead of a 9bit one. This means that you might not even be writing or reading into someone elses space.

C++ is fast, and one of the reasons that it is fast is becaurse there are very few checks on what you are doing, if you ask for some memory, then the programming language will assume that you know what you are doing, and if the operating system does not complain, then everything will run.

Martin Kristiansen
  • 9,875
  • 10
  • 51
  • 83
1

There is no runtime checking on the index you are giving, accessing element 10 is incorrect but possible. Two things can happen:

  • if you are "unlucky", this will not crash and will return some data located after your array.
  • if you are "lucky", the data after the array is not allocated by your program, so access to the requested address is forbidden. This will be detected by the operating system and will produce a "segmentation fault".
neodelphi
  • 2,706
  • 1
  • 15
  • 22
0

There is no problem! You are just accessing memory that you shouldn't access. You get access to memory after the array.

sim642
  • 751
  • 7
  • 14
0

This is not Java. In C or C++ there is no bounds checking; it's pure luck that you can write to that index.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Nim
  • 33,299
  • 2
  • 62
  • 101
  • 1
    That his program compiles has nothing at all to do with luck. And if it runs "successfully", I'd say that's _unlucky_. – Lightness Races in Orbit Jul 21 '11 at 09:05
  • @Tomalak, hey not fair, the question has changed - significantly since I answered it - there was no indication as to whether the OP expected something at compile time or run time - so I assumed run time - even in Java this is runtime exception (AFAIK). Though the general points are still valid - and interestingly repeated multiple times in other answers... – Nim Jul 21 '11 at 09:42
  • Many of the answers to this question are misleading in small ways. – Lightness Races in Orbit Jul 21 '11 at 09:43
0

isSeedPos doesn't know how big the array is. It is just a pointer to a position in memory. When you point to isSeepPos[10] the behaviour is undefined. Chances are sooner or later this will cause a segfault, but there is no requirement for a crash, and there is certainly no standard error checking.

Tom
  • 5,219
  • 2
  • 29
  • 45
0

Writing to that position is dangerous.

But the compiler will let you do it - Effectively you're writing one-past the last byte of memory assigned to that array = not a good thing.

C++ isn't a lot like many other languages - It assumes that you know what you are doing!

Seb Holzapfel
  • 3,793
  • 1
  • 19
  • 22
0

Both C and C++ let you write to arbitrary areas of memory. This is because they originally derived from (and are still used for) low-level programming where you may legitimately want to write to a memory mapped peripheral, or similar, and because it's more efficient to omit bounds checking when the programmer already knows the value will be within (eg. for a loop 0 to N over an array, he/she knows 0 and N are within the bounds, so checking each intermediate value is superfluous).

However, in truth, nowadays you rarely want to do that. If you use the arr[i] syntax, you essentially always want to write to the array declared in arr, and never do anything else. But you still can if you want to.

If you do write to arbitrary memory (as you do in this case) either it will be part of your program, and it will change some other critical data without you knowing (either now, or later when you make a change to the code and have forgotten what you were doing); or it will write to memory not allocated to your program and the OS will shut it down to prevent worse problems.

Nowadays:

  • Many compilers will spot it if you make an obvious mistake like this one
  • There are tools which will test if your program writes to unallocated memory
  • You can and should use std::vector instead, which is there for the 99% of the time you want bounds checking. (Check whether you're using at() or [] to access it)
Jack V.
  • 1,381
  • 6
  • 20
  • What compilers do spot that? And btw, C++ doesn't let you write to arbitrary memory. – R. Martinho Fernandes Jul 21 '11 at 09:40
  • Thank you. I may be mistaken on compiler checking, I wasn't actually sure. What do you mean, C++ doesn't let you write to arbitrary memory? Do you mean that if you run your program on a standard protected operating system, it will write to virtual memory whatever language its written in? Or that you can't assign a pointer to whatever you want and dereference it? Or that writing to address 0 is a real hassle? Or something else I was stupidly missing? – Jack V. Jul 21 '11 at 14:19
  • I mean that, even though you might write code that looks like it does so, or that compilers might actually compile that, C++ requires you to always write to well-defined places. Attempting to write data anywhere else in memory is undefined behavior. – R. Martinho Fernandes Jul 21 '11 at 14:27
  • Oh, I see. I'm sorry. Huh. *headache* Isn't there some exception for using char to access uninitialised memory? Or is writing device drivers in C++ officially impossible (even if most compilers do do the obvious thing when writing to a memory location)? – Jack V. Jul 21 '11 at 15:25
  • If you a device mapped to memory, you can write to the addresses that have been mapped, no problem. But if you declare an array of size 3, you can't write in what would be index 3 of that array. To access that kind of memory you need a pointer to it, or an array that has its exact size. You can't "cheat" with a smaller array. – R. Martinho Fernandes Jul 21 '11 at 15:28