1

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.

Kazekage Gaara
  • 14,972
  • 14
  • 61
  • 108
fskking
  • 35
  • 4
  • 1
    Looks like they mean `if(*marginalProbability > 0)` – Almo Mar 09 '12 at 16:33
  • 5
    The new operator for arrays automatically computes the size of elements, so it should really be `new double[10]` for an array of 10 `double`s. You're now probably allocating something like 80 doubles. Also, `std::fill(marginalProbability, marginalProbability+10, 0.0);` is more convenient that `memset()`. – André Caron Mar 09 '12 at 16:35
  • @AndréCaron: and `new double[10]()` is more convenient than `std::fill()`. – Mike Seymour Mar 09 '12 at 16:46
  • 3
    Every single line above the `printf`s is wrong. – Mooing Duck Mar 09 '12 at 17:17
  • 1
    @MooingDuck *Including* the `printfs`. “smaller”? WTF …? – Konrad Rudolph Mar 09 '12 at 17:23
  • @KonradRudolph: Not understanding the intent of the code, I can't say for certain that the `printf`s are _wrong_, though they very well could be. – Mooing Duck Mar 09 '12 at 17:24
  • 2
    @MooingDuck: for one thing, they don't flush the standard output, so they could very well print *nothing* to the screen.. – André Caron Mar 09 '12 at 17:35
  • @AndréCaron: He's removed a lot of context. It may very well flush after. We don't know that. – Mooing Duck Mar 09 '12 at 18:21
  • @André I’m pretty sure streams are flushed automatically when they’re closed, i.e. at the end of the program. – Konrad Rudolph Mar 10 '12 at 01:07
  • 1
    @KonradRudolph: OP didn't specify that this was the end of the program. Besides, my comment was meant to be taken tongue in cheek, as in "even the print statements don't work as intended ;-)". – André Caron Mar 10 '12 at 01:36

6 Answers6

5

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.

trojanfoe
  • 120,358
  • 21
  • 212
  • 242
4

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).

2

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.
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
0

As others mentioned already this is a bug. A more subtle variant of the bug can be found here: Warning comparison between pointer and integer.

a modern gcc (13.1) errors out on this:

:7:9: error: ISO C++ forbids comparison between pointer and integer [-fpermissive] 7 | if(y>5) { | ~^~ Compiler returned: 1

Older version of gcc might require -Wextra:

The option -Wextra also prints warning messages for the following cases:

A pointer is compared against integer zero with <, <=, >, or >=.
ted
  • 4,791
  • 5
  • 38
  • 84
0

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++.

Puppy
  • 144,682
  • 38
  • 256
  • 465
0

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;
}
111111
  • 15,686
  • 6
  • 47
  • 62
  • But why would they be printing "larger" if the pointer is valid, and "smaller" if it's not valid? – Almo Mar 09 '12 at 16:34
  • I have no idea. unless they are saying it could be larger (because it fit in memory) or it must be smaller if it is going to fit in memory. The code really doesn't look very food. – 111111 Mar 09 '12 at 16:39
  • i am very disappointed the code(of course i changed some unimportant lines) is from opencv. – fskking Mar 09 '12 at 17:00
  • 1
    @fskking: This code is wrong. If you got it from opencv, I think you copied it wrong, I'd be shocked if opencv actually does this. – Mooing Duck Mar 09 '12 at 17:20