Difference between two C snippets - c

I am at a loss to explain why these two C snippets do not behave the same way. I am trying to serialize two structs, eh and ah, as a single buffer of bytes (uint8_t). The first code block works, the second does not. I can't figure out the difference. If anyone can explain it to me it would be greatly appreciated.
Block 1:
uint8_t arp_reply_buf[sizeof(eh) + sizeof(ah)];
uint8_t *eh_ptr = (uint8_t*)&eh;
for (int i = 0; i < sizeof(eh); i++)
{
arp_reply_buf[i] = eh_ptr[i];
}
uint8_t *ah_ptr = (uint8_t*)&ah;
int index = 0;
for (int i = sizeof(eh); i < (sizeof(eh) + sizeof(ah)); i++)
{
arp_reply_buf[i] = ah_ptr[index++];
}
Block 2:
uint8_t arp_reply_buf[sizeof(eh) + sizeof(ah)];
arp_reply_buf[0] = *(uint8_t *)&eh;
arp_reply_buf[sizeof(eh)] = *(uint8_t *)&ah;

In the second example you only set the values in two indexes:
arp_reply_buf[0]:
arp_reply_buf[0] = *(uint8_t *)&eh;
arp_reply_buf[sizeof(eh)]:
arp_reply_buf[sizeof(eh)] = *(uint8_t *)&ah;

Related

What am I doing wrong with this for loop in C?

I'm trying to implement the below code in a for loop, to avoid needing to have every XOR term written out separately.
unsigned int check_0 = P0^en[2]^en[4]^en[6]^en[8]^en[10]^en[12]^en[14]^en[16]^en[18]^en[20]^en[22]^en[24]^en[26]^en[28]^en[30];
This is what I've written, but it doesn't work. Can someone please let me know what I'm doing wrong?
unsigned int check_0z = P0;
unsigned int check_0 = 0;
int i = 2;
for (i = 2; i > 30; i += 2){
check_0 = check_0z^en[i];
check_0z = check_0;
}

Casting integer to uint8_t

I am trying to write a small function that calculates difference for each pixel. However, seems like casting int to uint8_t ( (uint8_t)temp ) is causing problems on a microprocessor at the very first iteration and leads to a restart
abs_diff = (uint8_t*)malloc(320*240 * sizeof(uint8_t));
for (int i = 0; i < 320*240; i++){
int temp = abs((int)_jpg_buf[i] - (int)_jpg_buf_prev[i]);
Serial.printf("abs %d\n", temp);
abs_diff[i] = (uint8_t)temp; // <- fails
}
P.S. not a C expert here

Why does this array not get fouled up?

I'm studying code to learn about Extended USB Controls and I came across this bit of code shown below. The function reverses an array's order. It's pretty straight forward, except for one thing. Why doesn't the code corrupt the array? Using the source and destination as the same variable should corrupt it, shouldn't it?
/*
* Convert a array of bytes from big endian to little endian and vice versa by inverting it
*/
static
uint8_t *raw_inv(uint8_t *data, int size) {
int ai = 0;
int bi = size - 1;
uint8_t a = 0;
uint8_t b = 0;
while (ai < bi) {
a = data[ai];
b = data[bi];
data[ai] = b;
data[bi] = a;
ai++;
bi--;
}
return data;
}
Ah: It's the 'static' declaration, isn't it?
It uses a and b as temporaries to hold the values it's exchanging. Only one temporary is needed -- this could be rewritten as:
while (ai < bi) {
a = data[ai];
data[ai] = data[bi];
data[bi] = a;
ai++;
bi--;
}

Concatenating uint8_t to a char*

im really new to C and im having a bit of a complication creating a char* from various uint8_t
My idea is to create a char* where in each location I place a number form a matrix
For example if I have a matrix with:
[1][2][3][4]
[5][6][7][8]
[9][0][1][2]
[3][4][5][6]
id like a char* thats "01234567890123456"
what im doing bit its not working is:
char* string = malloc(sizeof(char)*matrix->height*matrix->width);
for (int i = 0; i < matrix->height ; ++i) {
for (int j = 0; j < matrix->width ; ++j) {
string[i*matrix->height+j] = matrix->value[i][j];
}
}
of course its not working but im a bit lost on how to proceed and I cant find more information regarding this problem.
Any help would be nice,
thanks
Since you're trying to print a string, you need the ASCII character for 0. So, simply add '0' to each number, like so
char* string = malloc(sizeof(char)*(matrix->height*matrix->width + 1));
for (int i = 0; i < matrix->height ; ++i) {
for (int j = 0; j < matrix->width ; ++j) {
string[i*matrix->width+j] = matrix->value[i][j] + '0';
}
}
string[matrix->height*matrix->width] = 0; //null terminator
Note however this isn't exactly the most portable solution.
Also, notice that you want to multiply i by the width, because if you didn't have a square matrix your calculation wouldn't work correctly.
It's kind of unnecessary to have sizeof(char), because the size of a char is defined to be 1 regardless of the byte size.

Save integer value as a byte value in char in ansi c

I want to save a ppm file as a P6. That mean bytes only. Also I want to save it in parallel way, so this is why I am using mmap to map memory.
This is a part of code where I am trying to save everything:
char* map;
//...
int offset = sprintf(map,"P6\n%d %d\n%d\n",x,y,k);
int counter = offset;
for(i = 0; i < x; i++)
{
for(j = 0; j < y; j++)
{
map[counter] = outputRed[i][j];
map[counter+1] = outputGreen[i][j];
map[counter+2] = outputBlue[i][j];
counter++;
}
}
The problem is that I am unable to save those values from Red, green and blue array (all are int) into map values.
Earlier I've simply used fputc with fopen(FILE,"wb") and that was doing everything nice, but now I cannot do it like this.
Can someone tell me how I can do it?
You have to increment the counter by 3 for each pixel:
map[counter] = outputRed[i][j];
map[counter+1] = outputGreen[i][j];
map[counter+2] = outputBlue[i][j];
counter += 3;
You can increment the counter after copying data for each pixel. This may be more easy to understand.
map[counter++] = outputRed[i][j];
map[counter++] = outputGreen[i][j];
map[counter++] = outputBlue[i][j];
Make sure the enough memory is allocated to map.

Resources