1

on my computer when I am declaring an array in C++, say for example this

int mynum[3];
mynum[0]=1;
mynum[1]=2;
mynum[2]=3;

mynum is an array which can hold 3 elements, now when I add this line

mynum[3]=4;

it crashes on Windows and on Ubuntu terminal ( stack smashing detected unknown terminated core dumped ) but when I use,

mynum[4]=56;
mynum[5]=34;
mynum[6]=23;

it does not gives any error ( when I use above three line in place of mynum[3] ) why is this happening ?

  • 1
    C++ doesn't have bounds-checking for plain arrays. Going out of bounds leads to *undefined behavior*. If it seems to work, you're "**un**lucky". – Some programmer dude Sep 17 '21 at 08:31
  • 1
    @Someprogrammerdude more importantly, undefined behaviour is (sadly) not checked for by default. There are plenty of downsides to that which is why its not enabled by default, but at least clang toolchain has sanitizers that can detect bugs like that. – Kaihaku Sep 17 '21 at 08:34

2 Answers2

3

Writing out of the bounds of an array has an undefined behavior. It may work by chance if that part of the memory is still in the data segment, and it may crash spectacularly. In any event, you should never assume any behavior for this action, and your program should never depend on it.

Mureinik
  • 297,002
  • 52
  • 306
  • 350
  • 1
    "t may work by chance if that part of the memory is still in the data segment" before that the compiler must translate it even though the code makes no sense. The compiler could as well treat OPs code equivalent to this code: `int main() {}` – 463035818_is_not_an_ai Sep 17 '21 at 08:35
  • @463035818_is_not_a_number if compiler can detect UB like that and rip out all code altogether why would it do that instead of throwing an error? Its an implementation detail for sure, but why would any implementor choose that over an error message? When I think of undefined behaviour, its something precisely what even compiler isn't aware of, it just blindly translates what you wrote into machine code, even if its broken and wrong. If it instead detects it and decides to do whatever anyway, I'd call it a compiler bug. – Kaihaku Sep 17 '21 at 08:41
  • Because it makes writing optimizers possible (or a lot easier) if the compiler can assume UB can not happen and remove paths where it does. See the links at the bottom of this page where the LLVM blog discusses the interaction between UB and optimization - https://en.cppreference.com/w/cpp/language/ub – Richard Critten Sep 17 '21 at 08:42
  • @Kaihaku I was refering to what would be conformant with the standard, what you can count on, what guarantees you get. When the code has UB: none. Imho once your code has ub, implementation details don't matter that much. Actually my point was that one should differentiate between code, which is an abstract description of a program, and the assembly which is about accessing real memory and the like – 463035818_is_not_an_ai Sep 17 '21 at 08:42
  • @RichardCritten I'm actually curious, how do you remove a path where UB happens without knowing that its UB? The only way it can happen is if it wasn't intended, which is a different thing from "when x then y". – Kaihaku Sep 17 '21 at 08:44
  • You need to read the LLVM blog it's not a 2 sentence explanation. Also the "Time Travel" link just below them. – Richard Critten Sep 17 '21 at 08:44
  • Invalid branches (with UB) can easily happen with ("correct") MACROs, the "dead" branches can be removed. – Jarod42 Sep 17 '21 at 08:51
0

This is because the array's size is fixed, and cannot be modified, and when you are trying to access mynum[4] this is out of bounds of the array size you've allocated, and you are trying to reach an illegal segment (that may be allocated for other purposes).

If you need an array-like storage (i.e., contiguous in memory) that is also dynamic in size, you can use std::vector

ronpi
  • 470
  • 3
  • 8