The same code is giving me two different outputs when I run it in two different places. This is the code;
#include <iostream>
using namespace std;
struct test {
int val;
};
int main() {
test* a;
cout << (a == NULL) << endl;
}
I get either 1 as the output:
or 0:
So, does an undefined pointer variable equals to NULL or not? What could be the reason for this variance?
Without being explicitly initialized, it would only be initialized to NULL or nullptr if declared at file level ("globally") or with static.
Otherwise it is undefined. It might be NULL or it might be any other value. You are assuming it will be NULL, so the most dangerous thing that can happen is it coincidentally being NULL in any tests you run, as that will not check your assumption.
These pointer variables are initialized to NULL.
int *p;
int main() {
// ...
}
int main() {
static int *p;
// ...
}
First of all it is undefined.
But usually if you run it in visual studio or similar platforms, in debug mode the compiler might initialize it to null terminated pointer, but in release mode it is just "garbage" which will return 0 from the "==" comparison.
Hope this helps!
Related
I was messing around with memory allocation. I was testing to see that, like Java, this program with give an exception.
int main() {
int* a = nullptr;
int b = *a;
std::cout << b;
}
Which indeed it does. Then I tested using malloc as a pointer to a, but not initializing a.
int main() {
int* a = (int*) malloc(sizeof(int));
int b = *a;
std::cout << b;
}
However, instead of throwing an exception, it prints out a seemingly random number in -842150451. I even tried replacing int with long:
int main() {
long* a = (long*) malloc(sizeof(long));
long b = *a;
std::cout << b;
}
However I got the same result. Then I tried it with short:
int main() {
short* a = (short*) malloc(sizeof(short));
short b = *a;
std::cout << b;
}
Then instead of the previous result, I got -12851. And it continued like this for every primitive type I could think of. What I want to know is, where are these numbers coming from and why these numbers specifically?
-842150451 is the two's complement representation of the value 0xCDCDCDCD, which is a common Visual Studio debugger value for heap-allocated uninitialized memory.
Uninitialized variables or memory have indeterminate values from the C++ specifications perspective, and using such values lead to undefined behavior. If you remember this, and always initialize such values or memory then you'll be alright.
All of your erroroneous programs have what's technically called undefined behaviour. Which means the behaviour of the program is unconstrained by the C++ standard, and therefore it's wrong to expect any particular outcome when you run your code.
C++ is quite unlike Java in this regard which specifies precise behaviours for most situations.
I'm playing around with pointers to understand this concept better
and wanted to ask
Why do i get null pointer as return for the second function?
and why it isn't possible to get the address 0x7fff15504044.
What is happening and where inside memory is the integer 5 stored,
when im working with it inside the function?.
#include <iostream>
using namespace std;
int* return_adress(int* input){ return input; }
int* return_adress_from_input(int input){ return &input; }
int main(){
int k = 3;
cout << return_adress(&k) << endl;
cout << return_adress_from_input(k) << endl;
}
Output:
0x7fff15504044
0
With int* return_adress_from_input(int input), input is a value copy of k in the caller. They are two different variables therefore with different addresses.
input goes out of scope conceptually once the closing brace of the function is reached.
The pointer &input then points to memory that you no longer own, and the behaviour of reading that pointer value (let alone dereferencing it) is undefined prior to C++14, and implementation defined from and including C++14.
Because you pass input by value, not by reference. Compiller first creates a local copy of input and then returns address of this local copy. To get the variable address use
int* return_adress_from_input(int& input){ return &input; }
In general, you get undefined behavior which can lead to returning nullptr in the particular case
On my PC i get
00AFFC80
00AFFBA8
so you are just lucky with zero return
what would be the result if I wrote this
int array1[2];
cout << array1[0] ;
and how can I do this pseudocode :
if array1[0] doesn't have a value then assign its value to 1
I'm using C++ on DevCPP
The elements of array are uninitialized, and it is undefined behaviour to read them before writing to them. Your program is ill-formed. There is no way to "check" for this; it is your responsibility to write a correct program.
The initial value of unassigned array values is undefined (unless the array element type is a class/struct, in which case the default constructor will be called for each array element). In your first example, the behavior is undefined since you have not initialized the array element before using it.
If you want to retain an "unassigned" status then you need to use a class that encapsulates this, for example using the nullable pattern for value types.
Consider using Boost.Optional: you'd declare the array as boost::optional<int> array1[2]; and then you can test if (array1[0]) to see if that particular element has a value.
There is one point that the answers I'm seeing thus far seem to have missed. It depends on where your array is defined.
If the array is local to a function, like:
int f() {
int array1[2];
cout << array1[0] ;
}
...then the other answers are correct: the content of array1 contains unspecified values, and your attempt to read the value and send it to cout gives undefined behavior.
On the other hand, you may have defined array1 as a global variable:
int array1[2];
int f() {
cout << array1[0];
}
In this case, the content of array1 is required to be initialized to 0 for any arithmetic type (or NULL for an array of pointers). In a case like this, writing out the value in array1[0] is perfectly fine and gives defined results -- it must be 0. In this case, there is no any way to tell whether an element of an array containing the value 0 has that value because it was automatically initialized to 0, or was assigned that value later.
If you really need to know whether a value has been written to a variable, it's possible to write a class that will do that:
template <class T>
class value {
T val;
bool assigned;
public:
value(T const init=T()) : assigned(false), val(init) {}
value &operator=(T const &t) {
assigned = true;
val = t;
}
operator T() { return val; }
bool was_assigned() { return assigned; }
};
// ...
value<int> array2[2];
if (!array2[0].was_assigned())
array2[0] = 1;
It's usually easier and more efficient to just define the type to always start out initialized to a known value, so you never really care about whether it's been assigned to or not though. In short, although this supports what you've asked for, my immediate reaction is that there's probably a better/cleaner way to accomplish your ultimate goal. Before you even consider using something like this, I'd strongly recommend stepping back from what you're doing, and trying to figure out if there's a better way to do it. My guess is that there is/will be (and if you can't find it, you might want to ask another question, telling us about why you're trying to do this, to see if somebody can see a more direct way to accomplish your goal).
As far I remember that depend on the OS
As other users said, you need to initialize a then use a for loop to test each value one by one and modify them, if they fulfill a condition, I leave you a C snippet:
/* Variable declaration and initialization to 0s (You can use another value as default )*/
int a[ 5 ] = { 0 };
/* If the array[ i ] has 0 as value */
for( i = 0; i < 5; i++){
if ( a[ i ] == 0 ){
a[ i ] = 1;
}
}
If you don't initialise the element yourself, the element will obtain the value from the memory location it is stored on now (and will most probably convert it to its data type). Consider this program :
#include <iostream>
using namespace std;
int foo(int A[])
{
cout << A[0] << A[1];
}
int main()
{
int array[2];
foo(array);
}
This will give the output 00.
But now consider this code :
int main()
{
int array[2];
cout << array[0] << array[1];
}
It will give some random integer output. This is so because the uninitialised array picks up the value stored on the memory location it now occupies. You can check its memory adress by &array[0] and print it in different data types for some thought provoking questions.
eg: cout << &array[0] << char(array[0]) << bool(array[0]) etc.
Please Explain the following code
#include <iostream>
using namespace std;
int main()
{
const int x = 10;
int * ptr;
ptr = (int *)( &x ); //make the pointer to constant int*
*ptr = 8; //change the value of the constant using the pointer.
//here is the real surprising part
cout<<"x: "<<x<<endl; //prints 10, means value is not changed
cout<<"*ptr: "<<*ptr<<endl; //prints 8, means value is changed
cout<<"ptr: "<<(int)ptr<<endl; //prints some address lets say 0xfadc02
cout<<"&x: "<<(int)&x<<endl; //prints the same address, i.e. 0xfadc02
//This means that x resides at the same location ptr points to yet
//two different values are printed, I cant understand this.
return 0;
}
*ptr = 8;
This line causes undefined behavior because you are modifying the value of a const qualified object. Once you have undefined behavior anything can happen and it is not possible to reason about the behaviour of the program.
Since x is a const int, the compiler will most likely, in the places where you use x, directly substitute the value that you've initialized with (where possible). So the line in your source code:
cout<<"x: "<<x<<endl;
will be replaced by this at compile time:
cout<<"x: "<<10<<endl;
That's why you still see 10 printed.
But as Charles explained, the behaviour is undefined, so anything could happen with code like this.
Similar to this question:
XCode 6.3 Warning : Comparison of address of 'myObject' not equal to null pointer is always true
with C++, I found that previously working code for evaluating null pointers stopped working:
struct AStruct
{
int x, y;
char *name;
};
AStruct& GetStruct()
{
return *(AStruct*)0;
}
int main(int argc, const char * argv[]) {
AStruct& mys = GetStruct();
if ( ! &mys) {
printf("null pointer \n");
}
else
{
printf("NOT a null pointer\n");
}
return 0
}
This always prints out
NOT a null pointer
I've tried other ways of pointer-to-reference checking:
if ( &mys == NULL)
if ( &mys == nullptr )
None of these worked.
Then I noticed the warning:
Reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false
But there are no suggested fixes.
What is the canonical way of checking null pointers these days?
You are not checking against a pointer, you are checking against a reference.
References are not supposed to be nullptr since they must refer to an existing value. Indeed what you are doing *(AStruct*)0 is not well defined since a reference shouldn't be able to generate undefined behaviour through "dereferencing it" but in this way you could trigger the problem.
If client code has a AStruct& then it can be sure that the reference points to something, you are breaking this condition.
If you need to work with references that can be null use a pointer, eg
AStruct* GetStruct()
{
return nullptr;
}
if (!GetStruct())
{
...
The fact that the code worked in a previous version of Xcode is a symptom of the fact that this is not well-defined code.
You don't have a pointer there; mys is a reference. Then when you check the value of &mys, you are checking the address of the reference.