No out of bounds error

2018-12-31 07:18发布

I have this code in C which takes in bunch of chars

#include<stdio.h> 
# define NEWLINE '\n'
int main()
{

char c;
char str[6];
int i = 0;
while( ((c = getchar()) != NEWLINE))
{
        str[i] = c;
        ++i;
        printf("%d\n", i);
}

return 0;
}

Input is: testtesttest

Output: 1 2 3 4 5 6 7 8 117 118 119 120

My questions are:

  1. Why don't I get an out of bounds (segmentation fault) exception although I clearly exceed the capacity of the array?

  2. Why do the numbers in the output suddenly jump to very big numbers?

I tried this in C++ and got the same behavior. Could anyone please explain what is the reason for this?

8条回答
初与友歌
2楼-- · 2018-12-31 07:23

You have to compile like this:

gcc -fsanitize=address -ggdb -o test test.c

There is more information here.

查看更多
看淡一切
3楼-- · 2018-12-31 07:31

C and C++, unlike Java, do not have Array Boundary checks. For example, if you have an array like this: int myArray[2] = {1, 2} and then later you print std::cout << myArray[5]; the compiler will not give any errors, rather it will print a garbage value.

查看更多
浪荡孟婆
4楼-- · 2018-12-31 07:34

When you access an array index, C and C++ don't do bound checking. Segmentation faults only happen when you try to read or write to a page that was not allocated (or try to do something on a page which isn't permitted, e.g. trying to write to a read-only page), but since pages are usually pretty big (multiples of a few kilobytes; on Mac OS, multiples of 4 KB), it often leaves you with lots of room to overflow.

If your array is on the stack (like yours), it can be even worse as the stack is usually pretty large (up to several megabytes). This is also the cause of security concerns: writing past the bounds of an array on the stack may overwrite the return address of the function and lead to arbitrary code execution (the famous "buffer overflow" security breaches).

The values you get when you read are just what happens to exist at this particular place. They are completely undefined.

If you use C++ (and are lucky enough to work with C++11), the standard defines the std::array<T, N> type, which is an array that knows its bounds. The at method will throw if you try to read past the end of it.

查看更多
余生请多指教
5楼-- · 2018-12-31 07:41

Writing outside array bounds (actually even just performing the pointer arithmetic/array subscripting, even if you don't use the result to read or write anything) results in undefined behavior. Undefined behavior is not a reported or reportable error; it measn your program could do anything at all. It's very dangerous and you are fully responsible for avoiding it. C is not Java/Python/etc.

查看更多
素衣白纱
6楼-- · 2018-12-31 07:43

Because C/C++ doesn't check bounds.

Arrays are internally pointers to a location in memory. When you call arr[index] what it does is:

type value = *(arr + index);

The results are big numbers (not necessarily) because they're garbage values. Just like an uninitialized variable.

查看更多
倾城一夜雪
7楼-- · 2018-12-31 07:44

C does not check array bounds.

In fact, a segmentation fault isn't specifically a runtime error generated by exceeding the array bounds. Rather, it is a result of memory protection that is provided by the operating system. It occurs when your process tries to access memory that does not belong to it, or if it tries to access a memory address that doesn't exist.

查看更多
登录 后发表回答