unassigned value in the int[ ] - c++

Would like to know in C++ what the value of unassigned integer in an int[] usually is.
Example
int arr[5];
arr[1]=2;
arr[3]=4;
for(int i=0;i<5;i++)
{
cout <<arr[i] <<endl;
}
it print
-858993460
2
-858993460
4
-858993460
we know that the array will be {?,2,?,4,?} ,where ? is unknown.
What will the "?" be usually?
When I tested , I always got negative value.
Can I assume in C++ unassigned element in the integer array is always less than or equal to zero?
Correct me if I'm wrong. When I study in Java unassigned element in array will produce null.

Formally, in most cases the very attempt to read an uninitialized value results in undefined behavior. So, formally the question about the actual value is rather moot: you are not allowed to even look at that value directly.
Practically, uninitialized values in C and C++ are unpredictable. On top of that they are not supposed to be stable, meaning that reading the same uninitialized value several times is not guaranteed to read the same value.
If you need a pre-initialized local array, declare it with an explicit initializer
int arr[5] = {};
The above is guaranteed to fill the array with integer zeros.

When I tested , I always got negative value.
The (previously) unused memory space seemed filled with the hex code 0xCC. However, as mentioned above -- several times -- you cannot rely on this.
In one of your comments you clarify your task:
im trying to create an int array let say of the size 100 and randomly insert postive integer into any position in the array. If the array is not full. how could i determine if that position in the array has never been assigned[?]
Fill the array with zeros (manually, or per AndrewT's answer). Since you are inserting positive integers only, all you have to test for is !0.

You can't know what this will produce, since it takes as value the bits that are in memory in that moment. So you can get ANY value, not only negative values.

The values contained in an unitialized area of memory can be anything, it is implementation depending. The most efficient implementation is to leave the memory as it was, so you will find in your array whatever was contained before. An important note: it is not something you can use as a random value. Some implementation (I have seen that, especially in the past, when compiling and running in debug mode) might put zeros in your memory, but it is uncommon. You simply should not rely on the content of uninitialized area of memory.
To understand if something has not been touched in your array, you can initialize it to some value like DEADBEEF:
http://en.wikipedia.org/wiki/Hexspeak
(Unless you are so unlucky that one of the values you have to insert corresponds exactly to DEADBEEF... :) )

These are garbage values, you cannot expect to work with these variables properly and they will not predict what it may result into. Whenever a variable gets allocated some portion of memory gets allocated for that variable and those portion may be used previously for some other unknown calculation which you cannot know, so you have to intialize those variables with some values to avoid usage of garbage values.

You are not assigning any value at these locations. So it will return garbage values from memory. You must put some values at these locations. Unimplemented locations will returned in some unexpected/unpredictable values.

Related

Can my program use unallocated memory on the free store without my knowledge?

When defining a variable without initialization on either the stack or the free store it usually has a garbage value, as assigning it to some default value e.g. 0 would just be a waste of time.
Examples:
int foo;//uninitialized foo may contain any value
int* fooptr=new int;//uninitialized *fooptr may contain any value
This however doens't answer the question of where the garbage values come from.
The usual explanation to that is that new or malloc or whatever you use to get dynamically allocated memory don't initialize the memory to some value as I've stated above and the garbage values are just leftover from whatever program used the same memory prior.
So I put this explanation to the test:
#include <iostream>
int main()
{
int* ptr= new int[10]{0};//allocate memory and initialize everything to 0
for (int i=0;i<10;++i)
{
std::cout<<*(ptr+i)<<" "<<ptr+i<<std::endl;
}
delete[]ptr;
ptr= new int[10];//allocate memory without initialization
for (int i=0;i<10;++i)
{
std::cout<<*(ptr+i)<<" "<<ptr+i<<std::endl;
}
delete[]ptr;
}
Output:
0 0x1291a60
0 0x1291a64
0 0x1291a68
0 0x1291a6c
0 0x1291a70
0 0x1291a74
0 0x1291a78
0 0x1291a7c
0 0x1291a80
0 0x1291a84
19471096 0x1291a60
19464384 0x1291a64
0 0x1291a68
0 0x1291a6c
0 0x1291a70
0 0x1291a74
0 0x1291a78
0 0x1291a7c
0 0x1291a80
0 0x1291a84
In this code sample I allocated memory for 10 ints twice. The first time I do so I initialize every value to 0. I use delete[] on the pointer and proceed to immediately allocate the memory for 10 ints again but this time without initialization.
Yes I know that the results of using an uninitialized variable are undefined, but I want to focus on the garbage values fro now.
The output shows that the first two ints now contain garbage values in the same memory location.
If we take the explanation for garbage values into consideration this leaves me only one conclusion: Between deleting the pointer and allocating the memory again something must have tampered with the values in those memory locations.
But isn't the free store reserved for new and delete?
What could have tampered those values?
Edit:
I removed the std::cout as a comment pointed it out.
I use the compiler Eclipse 2022-06 comes with (MinGW GCC) using default flags on Windows 10.
One of the things you need to understand about heap allocations is that there is always a small control block also allocated when you do a new. The values in the control block tend to inform the compiler how much space is being freed when delete is called.
When a block is deleted, the first part of the buffer is often overwritten by a control block. If you look at the two values you see from your program as hex values, you will note they appear to be addresses in the same general memory space. The first looks to be a pointer to the next allocated location, while the second appears to be a pointer to the start of the heap block.
Edit: One of the main reasons to add this kind of control block in a recently deallocated buffer is that is supports memory coalescence. That two int signature will effectively show how much memory can be claimed if that space is reused, and it signals that it is empty by pointing to the start of the frame.
When defining a variable without initialization on either the stack or the free store it usually has a garbage value, as assigning it to some default value e.g. 0 would just be a waste of time.
No. The initial value of a variable that is not initialized is always garbage. All garbage. This is inherent in "not initialized". The language semantics do not specify what the value of the variable is, and reading that value produces undefined behavior. If you do read it and it seems to make sense to you -- it is all zeroes, for example, or it looks like the value that some now-dead variable might have held -- that is meaningless.
This however doens't answer the question of where the garbage values come from.
At the level of the language semantics, that question is non-sensical. "Garbage values" aren't a thing of themselves. The term is descriptive of values on which you cannot safely rely, precisely because the language does not describe where they come from or how they are determined.
The usual explanation to that is that new or malloc or whatever you use to get dynamically allocated memory don't initialize the memory [so the] values are just leftover from whatever program used the same memory prior.
That's an explanation derived from typical C and C++ implementation details. Read again: implementation details. These are what you are asking about, and unless your objective is to learn about writing C and / or C++ compilers or implementations of their standard libraries, it is not a particularly useful area to probe. The specifics vary across implementations and sometimes between versions of the same implementation, and if your programs do anything that exposes them to these details then those programs are wrong.
I know that the results of using an uninitialized variable are undefined, but I want to focus on the garbage values fro now.
No, apparently you do not know that the results of using the value of an uninitialized variable are undefined. If you did, you would not present the results of your program as if they were somehow meaningful.
You also seem not understand the term "garbage value", for in addition to thinking that the results of your program are meaningful, you appear to think that some of the values it outputs are not garbage.

hex subtraction result is not shown as expected [duplicate]

I am using a code sample to check the distance between two integers like in the answer of this question.
int i = 0, j = 0;
std::cout << &i - &j;
From my understanding of the memory representation, these memory addresses of these two variables should be next to each other and the difference should be exactly 1.
To my surprise, running this code with MS compiler in VS2017 prints 3 and running the same code with GCC prints 1.
Why this happens, is something wrong with VS?
C++ standard does not make any requirements for C++ compilers to allocate variables with automatic storage duration in any particular way, including making them contiguous in memory. In fact, compiler may choose to not allocate any memory to a variable, optimizing it out completely.
That is why subtracting pointers makes sense only when they both point to memory inside the same array, or one element past the end of it. In all other situations, including yours, you get undefined behavior.
The pointer arithmetic you tried has undefined behavior:
If the pointer P points to the ith element of an array, and the
pointer Q points at the jth element of the same array, the
expression P-Q has the value i-j, if the value fits in std::ptrdiff_t.
Both operands must point to the elements of the same array (or one
past the end), otherwise the behavior is undefined. If the result does
not fit in std::ptrdiff_t, the behavior is undefined.

The initial value of the array is not assigned to zero by some computers in the fortran. Why is that? [duplicate]

I just begin learning Fortran, and I come across this issue. Consider the following simple code.
PROGRAM random
INTEGER, DIMENSION(12):: array
PRINT *, array
END PROGRAM random
The array is not assigned value, but can be printed, and it seems to have a few random elements and several zero elements. However, if I consider a shorter array, say I declare
INTEGER, DIMENSION(5):: array
then the printed array has all elements = 0. I wonder what is happening here?
When you define an array and try to look at the values it contains (i.e. by printing) before initialising it, the behaviour is undefined. It depends on compiler to compiler. While one compiler may automatically set all the values to zero (which many of us think that to be the default), another compiler may set it to completely random values. Which is why you are seeing the array values sometimes zero and sometimes not.
However, many of the compilers have options to initialise an unassigned array to zeros at compiler level. It is always advised that one should initialise an array always before using it!
If you do not initialize the variable you are seeing whatever happens to be in the memory that your variable occupies. To initialize your array to 0, use the statement:
integer, dimension(12) :: array
array = 0
If you do not initialize your variable before accessing it, your are using undefined behavior and your program is invalid.

C++ indexing beyond an array's size

My code takes an int input and sets that as the array's size, and I have some test prints that print out the index of the array starting from 0 to 4..
std::cout<<array[0]<<std::endl;
std::cout<<array[1]<<std::endl;
std::cout<<array[2]<<std::endl;
std::cout<<array[3]<<std::endl;
std::cout<<array[4]<<std::endl;
However, I noticed that if the input is smaller than 5, say 2 for instance, then the first two cout print out correctly, but then the rest print out 0 or random numbers like 17 and 135137. Is this an out of bounds thing that happens when you index beyond the array size or is this a problem in my code? (I know I have to change the print statements)
The arrays are dynamically allocated by the way, which I think shouldn't matter.
Is this an out of bounds thing that happens when you index beyond the array size or is this a problem in my code?
Both.
Assuming array itself has a size of at least 5 elements, the initial contents of it before you set the values to anything are undefined; essentially random (they're just whatever happened to be hanging out in that particular block of memory that your array now occupies). If array itself has a size of less than 5, the values are still undefined but accessing them also runs the risk of crashing the program. In either case, the fact that you are printing values beyond the end of the initialized, valid data in your array is a problem with your code.
If you allocate an array of n elements, accessing the (n+1)th element is undefined behaviour (UB). (Note after comments: The (n+1)th element is the element with index n. So if array has only size 3, accessing array[3] already causes UB).
So, yes it is an "out of bounds thing" and it is a problem of your code (because it's you who accesses the array beyond its size.
Why not loop to print out simply the existing element instead of hardcoding the indices?

Unexplained C++ default int values

I've been refactoring some code and I noticed some wonky behavior involving an uninitialized int array:
int arr[ARRAY_SIZE];
I set a break-point and it seems all values default to -858993460. Is there something special with this value? Any ideas why they don't default to 0?
-858993460 is, in hex, CCCCCCCC, which Visual Studio puts as default in DEBUG MODE. This is to make it easier for you to notice that you forgot to initialize the variable. In release mode it could be anything.
I’m actually unsure why mouseBufferX isn’t an element of 10 items (if this does compile and that isn’t 10 elements). But I am pretty sure that the standard says statics are initialized before nonstatics. Anyways, I personally hate using defines and consts to declare ints. Use an enum instead.
C++ doesn’t default anything to 0, so you MUST assign something a value before using it. Static variables are exceptions to this rule as they are set to zero by default. But I’ll note that the use of static variables is discouraged, and some languages (such as C#) do not allow you to declare static variables in a function.
There is no "default" in C++ -- variables and array elements, until initialized by your code, will contain whatever was in memory last.
In other words, when these variables are declared, a space in memory is reserved for their use. The bits in memory left over from the last time that memory was used are still there, causing your variables to initially appear as if they're filled with "garbage". The reason that memory isn't always zeroed out right away is speed -- it takes time to zero out memory.
You can initialise your array using a loop, or use this trick (at risk of being much less readable):
int mouseBufferX[mosueBufferSize] = { 0 };
This works because when you use a list of values to initialize the array, and there's less literal values than the number of elements in the array, the remaining elements always get initialized to 0.
You need to explicitly set the values for the array - they do not "default" to anything.
Try:
memset(mouseBufferX,0,sizeof(mouseBufferX));
//or
int mouseBufferX[mouseBufferSize] = {0};
//and, in C++ this *might* work too (fuzzy memory!):
int mouseBufferX[mouseBufferSize] = {};
C++ doesn't initialize variables. When a chunk of memory is allocated for the variable, that chunk of memory is left as-is and contains the value it did when it was allocated.
However, some compilers (like g++, I believe) will automatically initialize things to 0 - but don't depend on this behaviour as it will make your code less portable.
To get an array to have all the values in it initialized to a value, you can do this:
int mouseBufferX[mouseBufferSize] = {0};
int mouseBufferY[mouseBufferSize] = {0};
You can provide as many values as you want in the initialization list and the elements will be assigned those values.
Sometimes in a debug build, the compiler will initialize memory to a known value to make it easier to detect bugs. If your compiler does this, it should be documented somewhere.
This is entirely at the discretion of the compiler, because the standard doesn't guarantee any initialization whatsoever in this case.
thats a really dangerous assumption your making.
on a good compiler you might get a constant default value like the closest to -infinity(edit: or 0xCCCCCCCC thx acidezombie24), otherwise you'll just get random numbers
ALWAYS initialize your variables
something like
static const int mouseBufferSize = 10;
int mouseBufferX[mouseBufferSize];
memset(mouseBufferX,0,sizeof(mouseBufferX));
int mouseBufferY[mouseBufferSize];
memset(mouseBufferY,0,sizeof(mouseBufferY));