Recently, after being very tired, I wrote the following code:
GLfloat* array = new GLfloat(x * y * z);
Which, of course should have been:
GLfloat* array = new GLfloat[x * y * z];
(Note the square brackets as opposed to the parenthesis.)
As far as I know, the first form is not valid, but g++ compiled it. Sure, it spat out a completely incomprehensible segfault, but it compiled.
Why?
GLfloat* array = new GLfloat(x * y * z);
Creates a pointer called array to an object of type GLfloat with a value of x * y * z.
Well, the result of new T() is a T*, so new GLFloat would return a GLFloat*. As long as x*y*z is valid to pass to the GLFloat constructor, it's valid code.
It's the same sort of thing as:
int * p = new int(42);
Well, the first expression is a pointer to a GLfloat with value (xyz), which is perfectly legal.
Related
Take a look at this function signature:
AudioBlock (SampleType *const *channelData, size_t numberOfChannels, size_t startSampleIndex, size_t numberOfSamples)
from here
The main type used if float* so let's think of the signature as
AudioBlock (float *const *channelData, size_t numberOfChannels, size_t startSampleIndex, size_t numberOfSamples)
What does float *const *channelData mean? channelData should be a const pointer to a float pointer? What is a const* something? I don't see the type of the inner pointer.
Suppose I want to create a vector of zeros so I can pass to AudioBlock:
std::vector<float> v(bufferOriginal.getNumChannels()*bufferOriginal.getNumSamples(), 0);
How do I get a float *const *channelData to this vector data?
What does float* const* mean?
float is a fundamental floating point type. T* is a pointer to T. const is a qualifier that applies to whatever is on the left side of it (except when it is the left most token in which case it applies to right). Since both qualifier and the pointer apply to left, it is easies to read from right to left (there are more complicated cases where this simplified rule of thumb is wrong):
float * const * // original
* const * float // reversed
* | const * | float // added spaces and separators
non-const pointer to | const pointer to | non-const float // translated to english
Arrays are an example of more complex cases where just right to left doesn't work. For the more complex rule that works with all compound types, see "clockwise rule" or "spiral rule".
So it's not possible to get a float* const * to the vector data then, right?
You could, if you had a vector like this:
std::vector<float*> vector_of_pointers;
float* const* ptr = vector_of_pointers.data();
You could make element of that vector point to your vector of floats.
vector_of_pointers.push_back(v.data());
This parameter declaration
float *const *channelData
means that the variable channelData (read from tight to left) is a pointer to a constant pointer (the pointer itself that is constant) to a non-constant object of the type float.
To make it more clear consider the following demonstrative program.
#include <stdio.h>
int main(void)
{
float x = 1.1f;
float y = 2.2f;
printf( "x = %f\n", x );
float * const px = &x;
// px = &y; // error: assignment of read-only variable ‘px’
*px = y;
printf( "x = %f\n", x );
float * const * ppx = &px;
// *ppx = &y; // error: assignment of read-only location ‘*ppx’
**ppx = 3.0f;
printf( "x = %f\n", x );
return 0;
}
Its output is
x = 1.100000
x = 2.200000
x = 3.000000
As you can see as the pointer px is a constant variable it has to be initialized when it is declared. You can not change it such a way that it will point to another variable. But you can use pc to change the value of the object pointed to by px. The variable ppx is a pointer to such a pointer.
code:- p = new int *[5]; where p is a pointer & declared as int **P; Please explain me that why there is a * in between new and [5].
When allocating an array using new you need to specify the type. The general pattern is:
type* x = new type[n];
Where type is the base type, x is the variable, and n is the number of entries. You can make this a pointer type by adding * to both sides:
type** x = new type*[n];
You can continue this indefinitely:
type**** x = new type***[n];
Though in practice you'd rarely see that since excessively deep structures like that are nothing but trouble.
In C++, by virtue of its C heritage, pointers and arrays are interchangeable, as in both these definitions are basically equivalent:
void f(int* x)
void f(int x[])
Internally you can use x as either a pointer or an array, or both:
int y = x[0];
int z = *x;
Likewise these are identical:
int y = x[1];
int z = *(x + 1);
In general the distinction between x[n] and *(x + n) is largely irrelevant, the compiler treats both as the same and the emitted machine code is identical. The [] notation is just a syntax element that helps make the code easier to follow.
I'm never used C++ before, and I used OpenCV background subtraction MOG (Mixture of Gaussian) function in Python and I need to understand how the program works, the OpenCV program line 123 there's command bgmodel.create( 1, frameSize.height*frameSize.width*nmixtures*(2 + 2*nchannels), CV_32F );.. I found the .create function is to allocate new data from here with I assumed the parameter inside was (int ndims, const int* sizes, int type), my question is what the * mean, is it multiplication or pointer?
The asterisk (*) has three use cases:
The multiply operator: 2 * 3
A pointer type declaration: int* p;
Dereferencing a pointer (making it a reference to the value the
pointer is pointing to): *p = 6;
Example:
int i;
int* p = &i; // Sorry, introducing another confusion, taking the address of i
*p = 2 * 3;
// Now *p and i have the value 6
In the question, only multiplications are involved
If we look at your example:
bgmodel.create( 1, frameSize.height*frameSize.width*nmixtures*(2 + 2*nchannels), CV_32F );
We want to know if the * is a pointer dereference or is it multiplication. The form a a pointer dereference is
*pointer_type;
Which doesn't work here as every * is preceded by another variable. If we look at the syntax for multiplication we have:
some_type * some_type;
Now that matches what we have with variables on each side of the *
Now lets say you want to dereference a pointer and multiply it with something. To do that we will wrap the dereferencing in parentheses
some_type * (*pointer_type);
I found a crazy mistake in my code.
I had written the following line:
GLfloat* points = new GLfloat(1024);
rather than
GLfloat* points = new GLfloat[1024];
I only just noticed it. My code has compiled and run a few times before I noticed the error. I realize that this is by fluke, but my question is what does the line I originally had do?
I notice that it looks kind of like the creation of a class using a pointer to allocated memory. Does it create a single GLfloat on the heap with the initial value of 1024.0? If this is true, why is it valid syntax? (GLfloat is not a class, is it?)
GLfloat is an OpenGL alias for float (i.e., typedef float GLfloat;). Consequently the code:
GLfloat* points = new GLfloat(1024);
Is equivalent to:
float* points = new float(1024);
Which allocates a floating point number and initializes it to 1024.0 and assigns its address to pointer points.
Yes, you are creating a single GLFloat on the heap initialized to 1024.0. You can initialize primitives with the same syntax as classes. e.g.
int i(10);
Would create an int on the stack initialized to 10.
what does the line I originally had do?
GLfloat* points = new GLfloat(1024);
Let us try to replace GLfloat with int, you will see that if GLFloat is a type similar to int or float, then you will have the following:
int * points = new int(1024);
The above statement means that you are creating a pointer to an int with initial value being 1024. So in your case, it means creating a pointer points to a variable with type being GLfloat and initial value as 1024.
It is equivalent to write the following in a condensed version:
int * points = new int;
*points = 1024;
See here for more explanation.
create a dynamic array
int testSize = 10;
float *spec = new float[testSize];
how do you point to spec which points to the dynamic arary?
I tried this but It didn't work.
float **specPtr;
*specPtr = &spec[0];
float **specPtr;
specPtr = &spec;
spec is a pointer,so spePtr is the pointer that point to spec
Your problem is that by putting the dereference operator operator, you're assigning what the pointer specPtr points to, not what it actually is.
Try this instead
float **specPtr;
specPtr = &spec; // Note the omission of the '*'