This question already has answers here:
Why don't I get a segmentation fault when I write beyond the end of an array?
(4 answers)
Closed 6 years ago.
I have declare an int array of just three elements but I notice that I can access to array indexes bigger
int x[3];
int length = sizeof(x)/sizeof(x[0]);
printf("\n the length defined is %i but I can still setting and getting other indexes")
One of the things that makes C fast is that it doesn't do any type of bounds checking on arrays. It expects programmers to know what they're doing to stay within the proper bounds.
Failure to do so means accessing a portion of memory outside the bounds of the array and leads to undefined behavior.
When accessing an index bigger than an array length, what you are actually doing is to "invade" a memory area that you are not supposed to access. This can lead to unexpected behavior of your application or a crash.
Related
This question already has answers here:
Undefined, unspecified and implementation-defined behavior
(9 answers)
Accessing an array out of bounds gives no error, why?
(18 answers)
Closed 2 years ago.
#include <stdio.h>
#include <conio.h>
int main() {
int arr[] = {1,2,3};
arr[3] = 4;
printf("%d", sizeof(arr) / sizeof(1)); // To print the length of arr
getch();
return 0;
}
I first created this array of length 3 and then at index 3 I put 4 as its value. So the length should be 4 now, but still, after compiling it is printing 3. Why?
Arrays in C do not automatically extend themselves if you index outside the defined range. When you write
arr[3] = 4;
you are writing outside the bounds of the array.
The problem is that C does not require any kinds of bounds checking on array accesses and places no requirement on the compiler or runtime environment to handle out-of-bounds indexing in any particular way - the behavior is undefined. Any result is possible, including appearing to work as expected. You could also overwrite another variable. You could corrupt the stack frame leading to a crash later.
An array's size is fixed over its lifetime. You can allocate space dynamically with malloc or calloc and resize it using the realloc function, but again that doesn't happen automatically, you have to write the code to keep track of the current size and resize as necessary.
Why is the length of the array 3 ...
Because you defined it like that here
int arr[] = {1,2,3};
Using [] and three initialisers, size 3, not going to change.
... when I have added 4 elements?
You did not add 4 elements, you created it with initially three elements, they were not added.
You did not even add a single element later.
In this code
arr[3] = 4;
you wrote a value to a memory location just behind the array. The array is not changed by that, especially not its size. Doing this causes Undefined Behaviour by the way.
C is like that, it allows you to do all kind of unwise things, without kindly telling you.
You cannot create an array and then try to resize it. Arrays have a fixed size. If you want to store data dynamically, that is, with variable size, you need to use data structure.
This question already has answers here:
Array index out of bound behavior
(10 answers)
Closed 2 years ago.
the code written below copies string from one array to another and i have declared the both arrays as static and i have given the size of the second array as '1' while the string size which is to be copied is greater than the size i have provided to the second array,still the program is running without any error and also coping the whole sting string and displaying it. if both the arrays are static then the size of second array 't' is increasing so that the it can holds the whole string.
#include<stdio.h>
void main()
{
char c[]="hello";
char t[1];
int i;
for(i=0;c[i]!='\0';i++)
{
t[i]=c[i];
}
t[i]='\0';
printf("%s",t);
}
then the size of second array 't' is increasing
No. The size is not increasing. You wite to the outside of the bounds of the array, and then read out of bounds and the behaviour of the program is undefined.
P.S. The program is ill-formed because main does not return int as is required.
if it is a an undefined behaviour then how the code is working and producing valid output
Because it is undefined behaviour. Any behaviour is possible when it is undefined. You cannot assume that the output wouldn't be valid because that is not guaranteed. Nothing is guaranteed when behaviour is undefined.
This question already has answers here:
No out of bounds error
(7 answers)
How dangerous is it to access an array out of bounds?
(12 answers)
Closed 3 years ago.
In C, I noticed I can write to static array off-limits, for example:
static char a[10] = {0};
for (int i=0; i<20; i++) {
a[i] = 'a'; // Should fail when i > 9
}
I expected to get segmentation fault but it executes just fine.
If static arrays were allocated on the stack, it would make sense, but they're not, so why is that so?
Note: static int arrays behave similarly. Didn't check other types.
Thanks.
Edit: This is not a duplicate since the other questions were not about static arrays. Unlike "regular" arrays, static arrays are allocated in BSS. The behavior might be different, which is why I'm asking separately.
You will only get a segmentation fault when you actually attempt to write to memory
that is an illegal address. Your example code writes beyond what you allocated for the array, but that isn't an address beyond what the OS determines is legal for you to use.
Even if you do not get a segmentation fault, your example code could corrupt other data structures in your code and cause major faulty behavior of a program, and possibly even worse, it can cause intermittent and difficult to debug faulty behavior.
This question already has answers here:
I want this to crash, but it doesn't
(4 answers)
Closed 7 years ago.
#include<stdio.h>
#include<stdlib.h>
int main()
{
int *a[10];
a[2] = (int*)malloc(sizeof(int));
a[2][3]=4;
printf("%d", a[2][3]);
return 0;
}
I have given only the memory equivalent of a single int to the pointer variable. How is that I am able to access an element at index 3 for that pointer of a single int?
That's because nothing is preventing you accessing arrays out of bound and this invokes undefined behavior. Any expected or unexpected behavior of program can be seen.
You can try but the behaviour of your program will be undefined.
C does not perform that kind of checking at runtime.
You're accessing some randomly set RAM element. This is a common C programming mistake and is one of the reason for many security flaws.
The Heartbleed bug would be a nice example, where people were able to read a good portion of the server RAM, by accessing elements outside of the array structure.
This question already has answers here:
Array index out of bound behavior
(10 answers)
Why out of bound array accessible in C? [duplicate]
(3 answers)
Closed 9 years ago.
int main()
{
int a[2] = {1,2};
a[2] = 3;
printf("\n\n%d %d %d\n\n",a[0],a[1],a[2]);
return 0;
}
I get output as 1 2 3
Why no error is thrown at run time or compile time?
Have you heard about all the security problems caused by buffer overruns? They exist because C doesn't have any automatic array bounds checking. It's the programmer's responsibility to ensure that they don't address outside the array limit, the compiler doesn't check for it.
Just make sure you don't address anything out of the boundary since, C doesn't check array bounds.
int a[2] is allocated as an automatic variable on the stack. In Windows the stack is initially allocated as 1MB for a process. So, what has really happened is that when the code assigned a[2] = 3; an area outside of the stack frame for main() was updated.
More often than not this causes a problem, such as a segmentation fault, but in simple programs stuff like this sometimes still works.
An interesting test would be to call a sub-routine that also defines and sets some automatic variables and after it returns print the value of a[2] to see if it got overwritten by the stack frame for the sub-routine? If you do this, please let me know the results!