Read/Write a single byte of a void* variable - c++

If I have
void *temp = malloc(128);
memset(temp, 0 , 128);
And I want to read the first byte alone, following is what I'm doing.
char a[2];
strncpy(a, (char*)temp, 1);
int p = a[0];
//p will be zero in this case
Q1. I'm sure there is a more elegant way to achieve the same. If so, what would it be?
Q2. Is there a way I can alter the value of that single byte alone?
Say I want the first byte to have the value equivalent to the int value 48 (i.e. 00110000)
How would I do that?
I was able to make no progress with the write.

you can cast it to char * then access the memory
char *buff = temp;
char p = buff[0]; // read first byte

Related

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

How can I add multiple ints to a character array, then pull them out?

I am trying to place 3 integers(byte size is 4) into a character string byte by byte using c. I then need to "extract" the integers out of the character array so I can do integer operations on them. I have looked around and could not find any solutions to this. I think this will require some type of pointer use or shifting, but I cannot figure out how to write it.
char str[12]="";
int a;
int b;
int c;
int x;
int y;
int z;
a=5;
b=7;
c=12;
I know that an int is 4 bytes. I would like to make it so the str char array has the following data in it.
str = |a1|a2|a3|a4|b1|b2|b3|b4|c1|c2|c3|c4|
*I do not want it like this. str=|'5'|'7'|'12'|
I then need to "extract" the integers out of the character array.
x=str[0-3]; //extracting a
y=str[4-7]; //extracting b
z=str[8-11]; //extracting c
After this, I should be able to write x=y+z and x will be equal to 19.
One way is to treat str as an int array instead:
int* istr = reinterpret_cast<int*>(str)
Then you can use e.g.
istr[0] = a;
istr[1] = b;
istr[2] = c;
and
x = istr[0];
y = istr[1];
z = istr[2];
The question is not well posed so you are getting different answers which may or may not be solving your problem. In my interpretation, here's what you need:
int i1, i2, i3;
char arr[sizeof(i1)+sizeof(i2)+sizeof(i3)];
memcpy(arr, &i1, sizeof(i1));
memcpy(arr+sizeof(i1), &i2, sizeof(i2));
memcpy(arr+sizeof(i1)+sizeof(i2), &i3, sizeof(i3));
Note that I'm being deliberately explicit with using sizeof(i) instead of just "4". It is fairly safe that integers will be 32-bit in whatever environment you are using, but this is safer and strictly speaking more correct.
The easiest solution is to use memcpy:
int nums[sizeof str / sizeof(int)];
std::memcpy(nums, str, sizeof nums);
// Do work on nums here...
The reinterpret_cast approach is undefined behaviour.
Use (void *) to get a pointer to x, byte by byte
for (int i = 0; i < sizeof(int); ++i) {
str[i] = (void *)(&x)[i];
}
This will copy the 4 bytes of x into str, one by one. (void )(&x) casts x as a char array (or void*, same thing), and [i] accesses the i_th byte of the array
then access elements of str the same way.
Do the same with y and z, and don't forget the offset

Function returns BYTE array

I want my function to return a BYTE array. The function is as follows.
BYTE sendRecieveData(BYTE control, unsigned int value){
//Open connection to LAC
HANDLE LACOutpipe;
HANDLE LACInpipe;
LACOutpipe=openConnection(MP_WRITE);
LACInpipe=openConnection(MP_READ);
//declare variables
BYTE bufDataOut[3];
BYTE bufDataIn[3];
DWORD bufInProcess;
DWORD bufOutProcess;
//sets CONTROL
bufDataOut[0]=control;
//sets DATA to be sent to LAC
BYTE low_byte = 0xff & value;
BYTE high_byte = value >> 8;
bufDataOut[1]=low_byte;
bufDataOut[2]=high_byte;
MPUSBWrite(LACOutpipe,bufDataOut,3,&bufOutProcess,1000);
MPUSBRead(LACInpipe,bufDataIn,3,&bufInProcess,1000);
MPUSBClose(LACOutpipe);
MPUSBClose(LACInpipe);
return bufDataIn[3];
}
It doesn't return a byte array and when I change BYTE to BYTE[] or BYTE[3] it gives me an error.
return bufDataIn[3]; means "return 4th element of bufDataIn array" and in this case it leads to undefined behaviour since the size of this array is 3.
You can allocate memory for this new array in the body of your function and return pointer to its first element:
BYTE* createArray(...)
{
BYTE* bufDataOut = new BYTE[3];
....
return bufDataOut;
}
Don't forget to delete it when you finish with it:
{
BYTE* myArray = createArray(...);
...
delete[] myArray;
}
Even better, use std::vector<BYTE> and get rid of this ugly memory management with it ;) This ensures that the memory is properly freed on any return path, even when exceptions are thrown.
Since your array is relatively small I'd recommend to pass your buffer as a function argument.
void sendRecieveData(BYTE control, unsigned int value, BYTE (&buffdataIn)[3] ).
Now, one will use this function as follows:
BYTE result[3] = {0};
sendRecieveData(3, 0, result);
This way you may avoid usage of dynamic memory allocation and make your code safer.

Writing data to memory in C++

I want to write a a mix of int, char, real in void *data.
I am using a file pointer to run through the data block.
Now my question is that since the data type is void, I have to typecast it to int while writing integer and char for writing string.
While typecasting I used the following sample code:
*((int *)data+0) = 14; //writing int
*((int *)data+4) = 5; //writing int, left a space of 4 bytes for int
*((char *)data+8) = 'a'; //writing char
*((char *)data+9) = 'f'; //writing char
But then while reading the values back it didnt give the correct value.
cout<<*((int *)data+0);
cout<<*((int *)data+3);
cout<<*((char *)data+8);
Is the way my code is written correct? I am doubtful about it as data is void.
*((int *)data+4) = 5; // writing 4th int
cout<<*((int *)data+3); // but reading third one
And just in case, ((int *)data+4) points to 4th integer (that is, 16th byte given int size = 4), not to 4th byte. That is, you code overwrites bytes 0-3, then 16-19, then 8th, then 9th. What you probably meant is: *(int *)( (char*)data + X )
Edited to correct mistake pointed out by MSalters
Apart from the typo that others have mentioned (data+3 instead of data+4), you also need to change e.g.
*((int *)data+4)
to
*((int *)data+1)
because adding 4 to an int * doesn't add 4 to the address, it adds 4 * sizeof (int).
If you need to write to an offset that is not a multiple of sizeof(int) (say, 7), you need:
*(int *)((char *)data+7)
For this reason, it might be better to make data a char * to start with, so you can just say
*(int *)(data+7)
Use a class or a struct.
Here, pointer arithmetics is misleading you. When you add 4 to an int * you are adding actually four times sizeof int.
If your data has a constant layout, why don't you just use a struct such as
struct MemoryLayout {
int _first;
int _second;
char _c1;
char _c2;
};
?
You're writing the second one with:
*((int *)data+4) = 5; // offset = 4
and reading it back with:
cout<<*((int *)data+3); // offset = 3
In addition, the (int*) cast is binding to data, not data+4 so that your 4 is scaled up by the size of an int.
If you really want to do this (and a struct is not a possibility due to variances in the data formats), you should cast data to a char*, then add the number of bytes to get the char offset, then cast that to your desired type.
That would be something like:
*((int*)((char*)(data + 0)) = 14; //writing int
*((int*)((char*)(data + 4)) = 5; //writing int
*((char*)data + 8) = 'a'; //writing char
*((char*)data + 9) = 'f'; //writing char
int Data;
//char Data;
//float Data;
FILE *File = fopen("File.txt","wb");
fwrite((char *)&Data,sizeof(Data),1,File);
fclose(File);
File = fopen("File.txt","rb");
fread((char *)&Data,sizeof(Data),1,File);
fclose(File);
...
int DataInt1 = 200;
char DataChar1 = 'N';
FILE *File = fopen("File.txt","wb");
fwrite((char *)&DataInt1,sizeof(DataInt1),1,File);
fwrite((char *)&DataChar1,sizeof(DataChar1),1,File);
fclose(File);
int DataInt2 = 0;
char DataChar2 = 0;
File = fopen("File.txt","rb");
fread((char *)&DataInt2,sizeof(DataInt2),1,File);
fread((char *)&DataChar2,sizeof(DataChar2),1,File);
fclose(File);
printf("%d %d!\n",DataInt2,DataChar2);

Assigning value to allocated char array fails

I simply allocate some memory for a character and wanna do then some pointer arithmetic.
In this case I wanna write '\x0a' to byte 32 as follows:
#define HDR_SIZE 32
int size = 52;
unsigned char *readXPacket = (unsigned char *) malloc (size * sizeof (unsigned char));
*readXPacket + HDR_SIZE = '\x0a';
When I try doing that I get the following error message: non-value in assignment. Anyone an idea what is wrong here?
Thanks
Change your assignment to:
*(readXPacket + HDR_SIZE) = '\x0a';
What's wrong with the obvious:
readXPacket[HDR_SIZE] = '\x0a';
which is both shorter and clearer. and as you are using C++, why not say:
unsigned char * readXPacket = new unsigned char[size];
Or better still:
std::vector <unsigned char> readXPacket( size );
and have C++ manage the memory for you.
Try...
*( readXPacket + HDR_SIZE ) = '\x0a';