A pointer greater than zero in c++, what does mean? - c++

I encountered a problem in c++. I read some codes,but there was a very wired usage of pointer. The code is following:
double* marginalProbability =
new double [10 * sizeof(marginalProbability[0])];
memset( marginalProbability, 0, 10 * sizeof(double) );
//................
//.................
if(marginalProbability>0)
printf("larger");
else
printf("smaller");
The question I'm asking is what does it mean that if(marginalProbability>0). It is a pointer greater than zero. I think that in a normal compiler, there are no addresses which will be equal to zero. Or are there any other meanings of that? Otherwise, this line seems meaningless. Thanks.

I think that's a bug and the original author meant something like:
if(marginalProbability[0]>0)
printf("larger");
else
printf("smaller");
I don't see why they would test if marginalProbability was valid if they have already called memset() on it unconditionally. Also the use of the words larger and smaller indicate a comparison of a value, not a pointer.

The NULL pointer is treated as if it were zero. That being said, this code is probably just wrong, as the comparison is guaranteed to be true (since memset would have crashed if the pointer was NULL).

In this case, 0 is being interpreted as a null pointer constant.
You can compare two pointers, but the result is unspecified unless they point to two elements of the same array; so that code is well-formed but meaningless.
I suspect the code is supposed to compare a probability value, *marginalProbability or marginalProbability[i], with zero. If it's intended to check whether the allocation succeeded, then it's wrong for three reasons:
it would have to use !=, since the result of > is unspecified;
it would have to be done before memset();
it would only be necessary if the allocation used new (std::nothrow); plain new throws std::bad_alloc on failure.

a pointer with the value of zero is a null pointer. A pointer to nothing. Checking that it is not zero (p!=0 is more common that p>0 although p!=nullptr is most correct) means that it is not null.
The code you have listed is also wrong. if the new operation fails it will not return a null pointer but throw an exceptions which will no be caught.
this is what it should be.
try{
std::vector<double> marginalProbability (10, 0.0);
}catch(const std::bad_alloc& e){
std::cerr << "no memory" << std::endl;
}

There are pointers which are 0. They are explicitly the "null" pointer which points to no current valid object. However, using </>in this case is pretty meaningless- there's no such thing as the 1 pointer, for example.
Also, that's C code pretending to be C++.

Related

Why is there a value printed and not NULL/0 after incrementing a pointer in C++?

I am fairly new to C++, so excuse if this is quite basic.
I am trying to understand the value printed after I increment my pointer in the following piece of code
int main()
{
int i = 5;
int* pointeri = &i;
cout << pointeri << "\n";
pointeri++;
i =7;
cout << *pointeri << "\n";
}
When I deference the pointer, it prints a random Integer. I am trying to understand, what is really happening here, why isn't the pointer pointing at NULL and does the random integer have a significance ?
The C++ language has a concept of Undefined Behavior. It means that it is possible to write code that does not constitute a valid program, and the compiler won't stop or even warn you. What such code does when executed is unknown.
Your program is a typical example. After the line int* pointeri = &i;, the pointer is pointing to the value i. After pointeri++ it is pointing to the memory location after the value i. What is stored at that location is unknown and the behavior of such code is undefined.
Needless to say, great care should be taken when coding in C++ in order to stay in the realm of defined behavior, in order to have meaningful and predictable results when running the program.
why isn't the pointer pointing at NULL
Because you haven't assigned or initialised the pointer to null.
and does the random integer have a significance ?
No.
Why is there a value printed ...
Because the behaviour of the program is undefined.
As you know, a "pointer" is simply an integer variable whose value is understood to be a memory address. If that value is zero, by convention we call it NULL and understand this to mean that "it doesn't point at anything." Otherwise, the value is presumed to be valid.
If you "increment" a pointer, its value is non-zero and therefore presumed to be valid. If you dereference it, you will either get "unpredictable data" or a memory-addressing fault.

What are null pointers used for [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I have just started using c++ and saw that their is a null value for pointers. I am curious as to what this is used for. It seems like it would be pointless to add a pointer to point to nothing.
Well, the null pointer value has the remarkable property that, despite it being a well-defined and unique constant value, the exact value depending on machine-architecture and ABI (on most modern ones all-bits-zero, not that it matters), it never points to (or just behind) an object.
This allows it to be used as a reliable error-indicator when a valid pointer is expected (functions might throw an exception or terminate execution instead), as well as a sentinel value, or to mark the absence of something optional.
On many implementations accessing memory through a nullpointer will reliably cause a hardware exception (some even trap on arithmetic), though on many others, especially those without paging and / or segmentation it will not.
Generally it's a placeholder. If you just declare a pointer, int *a;, there's no guarantee what is in the pointer when you want to access it. So if your code may or may not set the pointer later, there's no way to tell if the pointer is valid or just pointing to garbage memory. But if you declare it as NULL, such as int *a = NULL; you can then check later to see if the pointer was set, like if(a == NULL).
Most of the time during initialization we assign null value to a pointer so that we can check whether it is still null or a address has been assign to it or not.
It seems like it would be pointless to add a pointer to point to
nothing.
No, it is not. Suppose you have a function returning optional dynamically allocated value. When you want to return "nothing" you return null. The caller can check for null and distinguish between 2 different cases: when the return value is "nothing" and when the return value is some valid usable object.
null value in C and C++ is equal to 0. But nullptr in C++ is different from it, nullptr is always a pointer type in C++. We assign a null value to a pointer variable for various reason.
To check whether a memory has been allocated to the pointer or not
To neutralize a dangling pointer so that it should not create any side effect
To check whether a return address is a valid address or not etc.
Most of the time during initialization we assign null value to a pointer so that we can check whether it is still null or a address has been assign to it or not.
Basically, pointers are just integers. The null pointer is a pointer with a value of 0. It doesn't strictly point to nothing, it points to absolute address 0, which generally isn't accessible to your program; dereferencing it causes a fault.
It's generally used as a flag value, so that you can, for example, use it to end a loop.
Update:
There seem to be a lot of people confused by this answer, which is, strictly, completely correct. See C11(ISO/IEC 9899:201x) §6.3.2.3 Pointers Section 3:
An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.
So, what's an address? It's a number n where 0 ≤ n ≤ max_address. And how do we represent such a number? Why, it's an integer, just like the standard says.
The C11 standard makes it clear that there's never anything to reference at address 0, because in some old pathologically non-portable code in BSD 4.2, you often saw code like this:
/* DON'T TRY THIS AT HOME */
int
main(){
char target[100] ;
char * tp = &target ;
char * src = "This won't do what you think." ;
void exit(int);
while((*tp++ = *src++))
;
exit(0);
}
This is still valid C:
$ gcc -o dumb dumb.c
dumb.c:6:12: warning: incompatible pointer types initializing 'char *' with an
expression of type 'char (*)[100]' [-Wincompatible-pointer-types]
char * tp = &target ;
^ ~~~~~~~
1 warning generated.
$
In 4.2BSD on a VAX, you could get away with that nonsense, because address 0 reliably contained the value 0, so the assignment evaluated to 0, which is of course FALSE.
Now, to demonstrate:
/* Very simple program dereferencing a NULL pointer. */
int
main() {
int * a_pointer ;
int a_value ;
void exit(int); /* To avoid any #includes */
a_pointer = ((void*)0);
a_value = *a_pointer ;
exit(0);
}
Here's the results:
$ gcc -o null null.c
$ ./null
Segmentation fault: 11
$

Can a unique_ptr be used with a negative index without leaking memory?

I read Are negative array indexes allowed in C? and found it interesting that negative values can be used for the index of an array. I tried it again with the c++11 unique_ptr and it works there as well! Of course the deleter must be replaced with something which can delete the original array. Here is what it looks like:
#include <iostream>
#include <memory>
int main()
{
const int min = -23; // the smaller valid index
const int max = -21; // the highest valid index
const auto deleter = [min](char* p)
{
delete [](p+min);
};
std::unique_ptr<char[],decltype(deleter)> up(new char[max-min+1] - min, deleter);
// this works as expected
up[-23] = 'h'; up[-22] = 'i'; up[-21] = 0;
std::cout << (up.get()-23) << '\n'; // outputs:hi
}
I'm wondering if there is a very, very small chance that there is a memory leak. The address of the memory created on the heap (new char[max-min+1]) could overflow when adding 23 to it and become a null pointer. Subtracting 23 still yields the array's original address, but the unique_ptr may recognize it as a null pointer. The unique_ptr may not delete it because it's null.
So, is there a chance that the previous code will leak memory or does the smart pointer behave in a way which makes it safe?
Note: I wouldn't actually use this in actual code; I'm just interested in how it would behave.
Edit: icepack brings up an interesting point, namely that there are only two valid pointer values that are allowed in pointer arithmetic:
§5.7 [expr.add] p5
If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.
As such, the new char[N] - min of your code already invokes UB.
Now, on most implementations, this will not cause problems. The destructor of std::unique_ptr, however, will (pre-edit answer from here on out):
§20.7.1.2.2 [unique.ptr.single.dtor] p2
Effects: If get() == nullptr there are no effects. Otherwise get_deleter()(get()).
So yes, there is a chance that you will leak memory here if it indeed maps to whatever value represents the null pointer value (most likely 0, but not necessarily). And yes, I know this is the one for single objects, but the array one behaves exactly the same:
§20.7.1.3 [unique.ptr.runtime] p2
Descriptions are provided below only for member functions that have behavior different from the primary template.
And there is no description for the destructor.
new char[max-min+1] doesn't allocate memory on the stack but rather on heap - that's how standard operator new behaves. The expression max-min+1 is evaluated by the compiler and results in 3, so eventually this expression is equal to allocating 3 bytes on the heap. No problem here.
However, subtracting min results in pointer which is 23 bytes beyond the beginning of the allocated memory returned by new and since in new you allocated only 3 bytes, this will definitely point to a location not owned by you --> anything following will result in undefined behavior.

C++ - Method that takes a pointer but receives an int

I am wondering how would I deal with a call to a function when an integer is passed into a function that accepts a pointer? In my case hasPlayedInTeam() accepts a pointer to Team, however, received an int. This causes the Q_ASSERT to hang.
In addition, is my problem also known as a null pointer? My professor has used that term several times in lecture, but I am not sure what he was referring to.
//main.cpp
Person p1("Jack", 22, "UCLA");
Q_ASSERT(p1.hasPlayedInTeam(0) == false);
//person.cpp
bool Person::hasPlayedInTeam(Team *pTeam) {
bool temp = false;
foreach (Team* team, teamList) {
if (team->getName() == pTeam->getName() {
temp = true;
}
}
return temp;
}
In your call:
p1.hasPlayedInTeam(0)
the integer literal 0 is converted to a NULL pointer. So, you are not actually "receiving" an integer; you are passing an integer, the compiler can automatically cast it to the null pointer (given the definition for NULL).
I think you can fix the definition of hasPlayedInTeam by either asserting that its argument is not NULL, or by returning a default value when NULL is passed in:
//person.cpp
bool Person::hasPlayedInTeam(Team *pTeam) {
assert(pTeam!=NULL); //-- in this case, your program will assert and halt
or:
//person.cpp
bool Person::hasPlayedInTeam(Team *pTeam) {
if (pTeam == NULL)
return false; //-- in this case, your program will not assert and continue with a sensible (it actually depends on how you define "sensible") return value
Yes, it sounds like your problem is a null pointer. A null pointer means that you have a pointer which isn't actually pointing to anything:
Team* team = NULL;
It so happens that in C++ NULL is a macro for the integer 0. Stroustrup has some comments on which one he prefers to use in code.
Function hasPlayedInTeam() looks for the argument of type "Team" whereas you are passing the argument of type "integer" which is wrong....
Yes, I think that you are referring to a null pointer in that situation.
To treat the case when an int is passed, you can overload the function and make it behave as you want it to do, when an int is passed.
In C++ there is NULL which is defined as 0 (in some standard header file, cstddef I think) so yes the integer you are passing is the null pointer. 0 is the only (as far as I know) integer that will automatically (implicitly) be converted to a pointer of whatever type is needed.
In practice, I think most people prefer to use NULL instead of 0 for the null pointer.
I'm not sure why it is hanging however, dereferencing the NULL pointer (in your statement pTeam->getName()) should cause the program to crash if you pass it NULL, not just hang.
Unfortunately the null pointer literal is one of the confused parts of the language. Let me try to recap:
For any type there is the concept of "pointer to that type". For example you can have integers and pointer to integers (int x; int *y;), doubles and pointer to doubles (double x; double *y;), Person and pointer to Person (Person x,*y;). If X is a type then "pointer to X" is a type itself and therefore you can even find pointers to pointers to integers (int **x;) or pointers to pointers to pointers to chars (char ***x;).
For any pointer type there is a null pointer value. It's a value that doesn't really point to an object, so it's an error to try to dereference it ("dereferencing" a pointer means reading or writing the object that is being pointed to). Note that the C++ language doesn't guarantee that you will get a message or a crash when you use a null pointer to get try to get to a non-existent pointed object but just that you should not do it in a program because consequences are unpredictable. The language simply assumes you are not going to do this kind of error.
How is the null pointer expressed in a program? Here comes the tricky part. For reasons that are beyond comprehension the C++ language uses a strange rule: if you get any constant integer expression with value zero then that can be (if needed) considered to be a null pointer for any type.
The last rule is extremely strange and illogical and for example means that
char *x = 0; // x is a pointer to char with the null pointer value (ok)
char *y = (1-1); // exactly the same (what??)
char *z = !! !! !! !! !! !!
!!! !! !! !! !! !!
!!!! !! !! !! !! !!
!! !! !! !! !! !! !!
!! !!!! !! !! !! !!
!! !!! !! !! !! !!
!! !! !!!!!! !!!!!!! !!!!!!1; // Same again (!)
and this is true for any pointer type.
Why is the standard mandating that any expression and not just a zero literal can be considered the null pointer value? Really no idea.
Apparently Stroustrup also found the thing amusing instead of disgusting like it should be (the last example with the "NULL" text written with an odd number of negations is present on "The C++ Programming Language" book).
Also note that there is a NULL symbol defined in standard headers that provide a valid definition for a null pointer value for any type. In "C" a valid definition could have been (void *)0 but this is not valid in C++ because void pointers cannot be converted implicitly to other pointer types like they do in "C".
Note also that you may find in literature the term NUL (only one L) but this is the ASCII character with code 0 (represented in C/C++ with '\0') and is a logically distinct thing from a pointer or an integer number.
Unfortunately in C++ characters are integers too and therefore for example '\0' is a valid null pointer value and the same goes for ('A'-'A') (they are integer constant expressions evaluating to zero).
C++11 increases complexity of these already questionable rules with std::nullptr_t and nullptr. I cannot explain those rules because I didn't understand them myself (and I'm not yet 100% sure I want to understand them).

Pointers assignment

What is the meaning of
*(int *)0 = 0;
It does compile successfully
It has no meaning. That's an error. It's parsed as this
(((int)0) = 0)
Thus, trying to assign to an rvalue. In this case, the right side is a cast of 0 to int (it's an int already, anyway). The result of a cast to something not a reference is always an rvalue. And you try to assign 0 to that. What Rvalues miss is an object identity. The following would work:
int a;
(int&)a = 0;
Of course, you could equally well write it as the following
int a = 0;
Update: Question was badly formatted. The actual code was this
*(int*)0 = 0
Well, now it is an lvalue. But a fundamental invariant is broken. The Standard says
An lvalue refers to an object or function
The lvalue you assign to is neither an object nor a function. The Standard even explicitly says that dereferencing a null-pointer ((int*)0 creates such a null pointer) is undefined behavior. A program usually will crash on an attempt to write to such a dereferenced "object". "Usually", because the act of dereferencing is already declared undefined by C++.
Also, note that the above is not the same as the below:
int n = 0;
*(int*)n = 0;
While the above writes to something where certainly no object is located, this one will write to something that results from reinterpreting n to a pointer. The mapping to the pointer value is implementation defined, but most compilers will just create a pointer referring to address zero here. Some systems may keep data on that location, so this one may have more chances to stay alive - depending on your system. This one is not undefined behavior necessarily, but depends on the compiler and runtime-environment it is invoked in.
If you understand the difference between the above dereference of a null pointer (only constant expressions valued 0 converted to pointers yield null pointers!) and the below dereference of a reinterpreted zero value integer, i think you have learned something important.
It will usually cause an access violation at runtime. The following is done: first 0 is cast to an int * and that yields a null pointer. Then a value 0 is written to that address (null address) - that causes undefined behaviour, usually an access violation.
Effectively it is this code:
int* address = reinterpret_cast<int*>( 0 );
*address = 0;
Its a compilation error. You cant modify a non-lvalue.
It puts a zero on address zero. On some systems you can do this. Most MMU-based systems will not allow this in run-time. I once saw an embedded OS writing to address 0 when performing time(NULL).
there is no valid lvalue in that operation so it shouldn't compile.
the left hand side of an assignment must be... err... assignable