This question already has answers here:
Accessing an array out of bounds gives no error, why?
(18 answers)
Closed 10 months ago.
When creating a pointer using new keyword or <stdlib.h>'s malloc, and put its size 0; what ever is the index number it doesnt give an error and works. ( i am not sure if this works if the size bigger then 0, because some times when i allocate a memory block and place an element outside its range program crashes).
My question : is this a c++ thing? Or just from my compiler? Is it safe to use it for arrays i don't want to limit it with specific size. Because i am thinking to use this in my game to make unlimited world generation and save it ( Not all terrain just the breakable and placable objects)
#include <iostream>
using namespace std;
int main() {
int* x = new int[0];
x[100] = 0;
cout << x[100];
return 0;
}
is this a c++ thing? Or just from my compiler?
It's a bug in your program. The behaviour of the program is undefined.
Is it safe to use it
It is not safe. The program is broken.
Related
This question already has answers here:
Are variable length arrays there in c++?
(2 answers)
Array[n] vs Array[10] - Initializing array with variable vs numeric literal
(1 answer)
Closed 1 year ago.
Given that user input is taken at runtime but array is created during compile time. How and why does this piece of code work?
#include <iostream>
using namespace std;
int main(){
int n;
cin>>n;
int arr[n]; //Why can I use this statement to create an array?
}
It's a non-standard extension, supported by gcc and clang.
It works by allocating space on the stack at the point the array is declared, a bit like alloca.
The memory allocated is automatically freed (by adjusting the stack pointer) when the function returns (or arr goes out of scope).
This question already has answers here:
No out of bounds error
(7 answers)
Closed 1 year ago.
I'm working on dynamic arrays for my c++ course, but I'm confused about the behavior of my dynamic arrays. For example, if I run this code:
int* myDynamicArr = new int[3];
for (int i = 0; i < 10; i++)
{
myDynamicArr[i] = i + 1;
cout << myDynamicArr[i] << endl;
}
I would expect it to not work since I only declared it as size 3. But when I run it, it prints out 0-9. Same thing if I do this:
char* myCharArr = new char[2];
strcpy(myCharArr, "ThisIsALongString");
cout << myCharArr;
It prints the full string even though it seems like it should fail. Can anyone explain what I'm doing wrong here? Thanks!
C++ does not perform bounds checking on arrays. So when you read or write past the bounds of an array you trigger undefined behavior.
With undefined behavior, your program may crash, it may output strange results, or it may (as in your case) appear to work properly.
Just because it could crash doesn't mean it will.
This question already has answers here:
Array with size 0 [duplicate]
(4 answers)
What is the purpose of allocating a specific amount of memory for arrays in C++?
(5 answers)
Closed 5 years ago.
Im reading up for a exam in C++ and just fideling around in order to get a better sense of the language. My understanding is that arrays in c++ are defined with a fixed length either before run time or dynamically. Knowing this I don't understand why C++ accepts this. I wouldn't think that it would be possible to add element to an array of length 0;
int * TestArray = new int[0];
TestArray[0]=10;
TestArray[1]=20;
TestArray[2]=30;
Writing to array elements outside of the valid size is Undefined Behaviour. It's a bug and your program is ill formed. But the compiler is not required to issue a diagnostic (although most will with the right warning options).
It's your responsibility to follow the rules.
You may not access any elements in a zero sized array. It results in undefined runtime behavior.
However, zero sized arrays are allowed for various reasons.
First, it allows you to make functions less complicated by skipping size checks:
void f(size_t n)
{
int * ptr = new int[n];
//...
delete[] ptr;
}
instead of:
void f(size_t n)
{
if (n>0)
{
int * ptr = new int[n];
//...
delete[] ptr;
}
}
Second, the intent was to make it easy for compiler writers to implement new using malloc, and this is the defined behavior for malloc.
The GCC c compiler docs give this reason:
"Zero-length arrays are allowed in GNU C. They are very useful as the last element of a structure that is really a header for a variable-length object: "
struct line {
int length;
char contents[0];
};
struct line *thisline = (struct line *)
malloc (sizeof (struct line) + this_length);
thisline->length = this_length;
[without it], you would have to give contents a length of 1, which means either you waste space or complicate the argument to malloc.
My professor told me that because c++ and c can access and write outside of array bounds,it is one of the main reasons they are used to create operating systems. For example you can even do something like
arr[-1]=5;
I believe it is worth mentioning.However this can lead to undefined behavior.
This question already has answers here:
Array size at run time without dynamic allocation is allowed? [duplicate]
(8 answers)
Closed 6 years ago.
I am reading C++ Primer plus on arrays, and it says the following
typeName arrayName[arraySize];
//Arraysize cannot be a variable whose value is set while the program is running"
However, I wrote a program
#include <iostream>
using namespace std;
int main()
{
int n;
cin>>n;
int array[n];
for(int i=0; i<n; i++)
{
cout<<array[i]<<endl;
}
}
And it works fine, I am able to set the size of the array during run time. I am not getting any compilation errors, or run time crashes.
Can someone explain what is happening?
Thanks
Some compilers like g++ allow the use of C variable length arrays and will happily compile the code without any warnings or error. This is not standard and is a compiler extension.
If you need an "array" and you do not know what the size will be until run time then I suggest you use a std::vector You can use it as a direct replacement to an array but it allows run time sizing and it offers a lot of other useful features.
This question already has answers here:
Accessing an array out of bounds gives no error, why?
(18 answers)
Closed 7 years ago.
Why this:
#include <iostream>
using namespace std;
int main() {
int a[1] = {0};
a[2048] = 1234;
cout << a[2048] << endl;
return 0;
}
does not give any compile-time error? (gcc 4.9.3)
Because this is legal C++.
You can try to dereference any pointer, even if it's not allocated by your program, you can try to access any cell of an array, even if it is out of bounds, the legality of an expression doesn't depend on the values of the variables involved in that expression.
The compiler doesn't have to run any static analysis to check whether you'll actually cause undefined behaviour or not, and shouldn't fail to compile if it assumes that you will (even when it is obvious that you will).
The problem is that you can't check all possible array access at compile-time (that would be way too expensive), so you'd have to arbitrarily draw a line somewhere (the problem being the word "arbitrarily", that wouldn't fit well in the standard).
Hence, checking that you won't cause undefined behaviour is the responsability of the programmer (or of specific static analysis tools).
Access to out of array range does not give any error
This is just because you were unlucky. :) What you can call it is "Undefined Behavior". Compiler is not doing any bound check on arrays, and what you are trying to do in statement a[2048] = 1234;is to write a memory location on stack, which is unused.