What does this cast assign? C Style Casting - c++

this is my first question on here.
I am currently trying to understand how this code works.
I basically want to assign a certain value to an array named "hv" of type uint8_t.
I do not quite understand what this cast does/how it works.
for (i = 0; i < 4; i++) {
hv[i] = *(uint16_t *)(h1 + 8 + i * 2);
}
I do understand that it is trying to cast the 2nd part to an uint16_t pointer but i do not know what the first asterisk does.
Help would be greatly appreciated.

I assume that h1 is a pointer. Otherwise this makes no sense at all.
The expression (h1 + 8 + i * 2) will give a new pointer, which is offseted relative to h1. Exactly by now much depends on sizeof(*h1). The offset vill be (8+i*2)*sizeof(*h1) bytes.
Putting (uint_16_t *) in front of this will convert it to a uint_16_t pointer. Putting an asterisk in front of that will give you the content of that memory location, treated as an uint_16_t.
The code is equivalent to:
for (i = 0; i < 4; i++) {
uint_16_t * tmp = (uint16_t *)(h1 + 8 + i * 2);
hv[i] = *tmp;
}

Related

Issue with pointers to memory allocation

Considering the following code block:
Byte* b = (Byte*) var.rawBuffer();
b += sizeof (Byte) * 9;
WhateverType* aptr = (WhateverType*) b;
WhateverType* anotherptr = aptr;
for (int i = 0; i < N; i++) {
assert(*anotherptr == aptr[i]);
anotherptr += sizeof (WhateverType);
}
Why do the assertion fail, sometimes? Is not scanning allocated memory using the [] operator with an index on the starting memory address equivalent to increment the pointer address by the size of the data type I am trying to read?
The problem is this line:
anotherptr += sizeof (WhateverType);
anotherptr is a WhateverType* pointer, not a Byte* pointer. When you perform arithmetic on a typed pointer, the total byte count is an even multiple of the type that the pointer is declared as.
So, in the line above, you are not telling the compiler to increment the pointer by just sizeof (WhateverType) number of bytes only, like you are expecting. You are actually telling it to increment the pointer by sizeof(WhateverType) number of elements, or in other words, by sizeof(WhateverType) * sizeof(WhateverType) number of bytes.
T *pointer = ...;
pointer += N;
Is effectively equivalent to the following:
pointer = reinterpret_cast<T*>(reinterpret_cast<byte*>(pointer) + (sizeof(T) * N));
Even the statement aptr[i] works the same way, as the expression pointer[N] is just syntax sugar for *(pointer + N).
For what you are attempting, you need to increment your anotherptr pointer by N=1 element, not by N=sizeof(WhateverType) number of elements. So, use this instead:
anotherptr += 1;
Or simpler:
anotherptr++; // or: ++anotherptr;

c++ : An array of the pointer float type with dynamic size

Is this Correct?
Will stereoBuffer be an array of the pointer float type with size mixQty (i.e. 2);
// C++ in Header File
float **stereoBuffer;
// in cpp file inside a function of init
mixQty = 2; // this will be passed in function
stereoBuffer = new float*[mixQty];
for (int i = 0; i < mixQty; ++i) {
stereoBuffer[i] = (float *)malloc(samplerate * 2 * sizeof(float) + 32768);
}
Help and Detail answer will be rewarded.
Is this Correct?
No. Mixing new and malloc() is not a good idea.
If you must use dynamic memory allocation, then read this: How do I declare a 2d array in C++ using new?
Otherwise, use an std::vector.
Will stereoBuffer be an array of the pointer float type
It will be (a pointer to the first element of) an array of type pointer-to-float.
Each element of this array will be a pointer to the first element of an array of float.
As gsamaras notes, mixing new and malloc like this is terrible practice. It's needlessly hard to correctly deallocate and there's no error checking. You could at least use std::vector<std::unique_ptr<float[]>> and let it take care of deallocation correctly for you.
using StereoBuffer = std::vector<std::unique_ptr<float[]>>;
StereoBuffer allocateStereoBuffer(size_t mixQty, size_t samplerate)
{
StereoBuffer buf(mixQty);
for (size_t i = 0; i < mixQty; ++i) {
buf[i] = make_unique<float[]>(samplerate * 2 * 32768); // ?
}
return buf;
}

How to make a copy of a byte array in c code?

I have the address of the first char in my byte array, and it's size:
const char *rawImageBytes, int size
And I want to copy the content to a different byte array. and then modify that one a bit.
This is whay I am doing now:
LOGI("FrameReceived will reach here 1");
modifiedRawImageBytes = rawImageBytes;
jint sizeWH = width * height;
jint quarter = sizeWH/4;
jint v0 = sizeWH + quarter;
for (int u = sizeWH, v = v0, o = sizeWH; u < v0; u++, v++, o += 2) {
modifiedRawImageBytes[o] = rawImageBytes[v]; // For NV21, V first
modifiedRawImageBytes[o + 1] = rawImageBytes[u]; // For NV21, U second
}
But I don't get the correct colours, as if I would to this in Java, instead of c++.
And I am assuming this happens, because I just do modifiedRawImageBytes = rawImageBytes; instead of actually copying the whole byte array, so that it can start in memory from another address pointer.
A bit of a beginner with c, so I'm lost at this, can someone help me understand what is done wrong?
PS: I am assuming that, because even if I send the rawImageBytes and not the modifiedRawImageBytes, it will still be modified
This is because const char * is a pointer. This mean it represent an address. So you guessed right, the new variable represent the same datas.
To avoid this you should create a copy.
char modifiedRawImageBytes[size];
//if the pointer come from function's param don't redeclare it ;)
std::memcpy(modifiedRawImageBytes, rawImageBytes, size*sizeof(char));
This code will allocate a new char array and then memcpy will copy in the previous array data in the new array.
Note that you need to includecstdio

Setting pointer out of it's memory range

I'm writing some code to do bitmap blending and my function has a lot of options for it. I decided to use switch to handle those options, but then I needed to either put switch inside a loop (I read that it affects performance) or to assign loop for each switch case (makes code way too big). I decided to do this using third way (see below):
/* When I need to use static value */
BYTE *pointerToValue = (BYTE*)&blendData.primaryValue;
BYTE **pointerToReference = &pointerToValue;
*pointerToReference = *pointerToReference - 3;
/* When I need srcLine's 4th value (where srcLine is a pointer to BYTE array) */
BYTE **pointerToReference = &srcLine;
while (destY2 < destY1) {
destLine = destPixelArray + (destBytesPerLine * destY2++) + (destX1 * destInc);
srcLine = srcPixelArray + (srcBytesPerLine * srcY2++) + (srcX1 * srcInc);
for (LONG x = destX1; x < destX2; x++, destLine += destInc, srcLine += srcInc) {
BYTE neededValue = *(*pointerToReference + 3); //not yet implemented
destLine[0] = srcLine[0];
destLine[1] = srcLine[1];
destLine[2] = srcLine[2];
if (diffInc == BOTH_ARE_32_BIT)
destLine[3] = srcLine[3];
}
}
Sometimes I might need to use srcLine[3] or blendData.primaryValue. srcLine[3] can be accessed easily with *(*pointerToReference + 3), however to access blendData.primaryValue I need to reduce pointer by 3 in order to keep the same expression (*(*pointerToReference + 3)).
So here are my questions:
Is it safe to set pointer out of its memory range if later it is
going to brought back?
I'm 100% sure that it won't be used when it's out of range, but can
I be sure that it won't cause any kind of access violation?
Maybe there is some kind of similar alternative to use one variable
to capture a value of srcLine[3] or blendData.primaryValue
without if(), like it's done in my code sample?
Because of #2, no usage, the answer to #1 is yes, it is perfectly safe. Because of #1, then, there is no need for #3. :-)
An access violation could only happen if the pointer were actually used.

Casting pointer to Array (int* to int[2])

How do I cast or convert an int* into an int[x]?
First, I know that pointers can be indexed. So I know that I can loop through the pointer and array and manually convert the pointer. (eg. a for loop with arr[i] = p[i]). I want to know if the same result can be achieved in fewer lines of code.
As an example I tried to cast pointer int* c = new int[x] to an array int b[2]
int a = 1;
int b[2] = { 2, 3 };
int* c = new int[b[1]];
c[0] = b[0];
c[1] = b[1];
c[2] = a;
I wanted to see what values were where, so I made a simple program to output addresses and values. The output is just below:
Address of {type: int} &a = 0031FEF4; a = 1
Address of {type: int[2]} &b = 0031FEE4; b = 0031FEE4
Address of {type: int[2]} &b[0] = 0031FEE4; b[0] = 2
Address of {type: int[2]} &b[1] = 0031FEE8; b[1] = 3
Address of {type: int*} &c = 0031FED8; c = 008428C8
Address of {type: int*} &c[0] = 008428C8; c[0] = 2
Address of {type: int*} &c[2] = 008428D0; c[2] = 1
Once I made sure I knew what was where I tried a few things. The first idea that came to mind was to get the address of the second element to the pointer's allocation, then replace the array's memory address with it (see the code just below). Everything I did try ultimately failed, usually with syntax errors.
This is what I tried. I really want this to work, since it would be the simplest solution.
b = &c[1];
This did not work obviously.
Edit: Solution:
Don't do it!
If it's necessary create a pointer to an array and then point to the array; this is pointless for any purposes I can fathom.
For more detailed information see the answer by rodrigo below.
First of all b is an array, not a pointer, so it is not assignable.
Also, you cannot cast anything to an array type. You can, however, cast to pointer-to-array.
Note that in C and C++ pointer-to-arrays are rather uncommon. It is almost always better to use plain pointers, or pointer-to-pointers and avoid pointer-to-arrays.
Anyway, what you ask can be done, more or less:
int (*c)[2] = (int(*)[2])new int[2];
But a typedef will make it easier:
typedef int ai[2];
ai *c = (ai*)new int[2];
And to be safe, the delete should be done using the original type:
delete [](int*)c;
Which is nice if you do it just for fun. For real life, it is usually better to use std::vector.
Though you can't reassign an array identifier.. sometimes the spirit of what you're doing allows you to simply create a reference and masquerade yourself as an array. Note: this is just a slight extension of rodrigo's answer... and it is still worth mentioning that there is probably a better way to accomplish whatever the task is.
#include <iostream>
int main() {
int x[1000] = {0};
for(int i = 0; i < 10; ++i) {
int (&sub_x)[100] = *(int(*)[100])(&x[i*100]);
//going right to left basically:
// 1. x[i*100] -- we take an element of x
// 2. &x[N] -- we take the address
// 3. (int(*)[100]) -- we cast it to a pointer to int[100]
// 4. *(...) -- lastly we dereference the pointer to get an lvalue
// 5. int (&sub_x)[100] -- we create the reference `sub_x` of type int[100]
for(int j = 0; j < 100; ++j) {
sub_x[j] = (i*100)+j;
}
}
for(int i = 0; i < 1000; ++i) {
if(i != 0) {
std::cout << ", ";
}
std::cout << x[i];
}
std::cout << std::endl;
}
As you'd expect the output just ends up printing 0-999 with no gaps
output:
0, 1, 2, ..., 999