Memory Allocation for union - c

In the following code
#include <stdio.h>
int main() {
union a {
int i;
char ch[2];
};
union a u;
int b;
u.ch[0] = 3;
u.ch[1] = 2;
printf("%d,%d,%d\n", u.ch[0], u.ch[1], u.i);
return 0;
}
The output I get is
3,2,515
Can anyone explain me why the value of i is 515?

union a {
int i;
char ch[2];
};
union a u; /* initially it contains gargage data */
All members of the union shares the common memory. In above case total of 4 bytes gets allocated for u because in 4 bytes(MAX memory needed) you can store both i and ch.
ch[1] ch[0]
----------------------------------
| G | G | G | G | => G means garbage/junk data, because u didn't initialized
----------------------------------
u
MSB LSB
when statement u.ch[0] = 3; executed only ch[0] initialized.
ch[1] ch[0]
--------------------------------------
| G | G | G | 0000 0011 | => G means garbage/junk data, because u didn't initialized
--------------------------------------
u
MSB LSB
And when u.ch[1] = 2; executed next 1 bytes gets initialized as
ch[1] ch[0]
------------------------------------------
| G | G | 0000 0010 | 0000 0011 | => G means garbage/junk data, because u didn't initialized
------------------------------------------
u
MSB LSB
As you can see above out of 4 bytes only first 2 bytes got initialized, still remaining 2 bytes are uninitialised so when you are printing u.i, its undefined behaviour.
If you want expected result then initialize then union variable first as
union a u = { 0 }; /* all 4 bytes got initialized at first instance itself, no chance of any junk data */
u.ch[0] = 3;
u.ch[1] = 2;
Now when you prints u.i, it prints data in whole 4 bytes which is 512 + 3 = 515 (In case of little enidian processor)

Related

Copy bits from a variable to another one, with bits swapped with LUT

In C language, I want to fill two 8-bit variables "a" and "b" with bits coming from a 16-bit variable "c".
The bits in the 16 bits variable are shuffled without any logical order, which can be for example :
a.4 | b.2 | b.6 | b.0 | a.0 | a.7 | a.6 | b.1 | b.2 | b.7 | b.4 | a.5 | a.1 | a.2 | b.3 | b.5
Is there a way to do that?
The goal is to have a quite lisible look-up table.
This code randomizes and shuffles bits in c after copying initial, you stated it is intended to be used in a embedded system but you didn't provide any information about which embedded system it is, it could be an arduino, it could be a obscure system from 80s, it could be a diy pcb with a random stm32 attached to it, we can't know :)
// Code is under public domain, use it like what you want
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <time.h>
int main() {
srand(time(NULL));
uint16_t initial = 4040; /* 24 will be shuffled */
uint16_t c = 0;
/* shuffle bits */
for(unsigned i = 0; i < sizeof(uint16_t) * 8; ++i) {
c ^= initial & (1 << (rand() % 16));
}
uint8_t a = 0;
uint8_t b = 0;
a = ((unsigned char*)&c)[0];
b = ((unsigned char*)&c)[1];
for(unsigned char i = 0; i < sizeof(uint16_t) * 8; ++i) {
printf("%c.%d = %d | ", ('a' * ((i < 8))) + ('b' * ((i >= 8))), ((i + 1) * (i < 8)) + ((i + 1 - 8) * (i >= 8)), ((a >> i)) & 1);
}
return 0;
}
This code will print this (obviously yours going to be random):
a.1 = 1 | a.2 = 0 | a.3 = 1 | a.4 = 1 | a.5 = 0 | a.6 = 1 | a.7 = 1 | a.8 = 1 | b.1 = 0 | b.2 = 0 | b.3 = 0 | b.4 = 1 | b.5 = 0 | b.6 = 1 | b.7 = 0 | b.8 = 0 |

Union value in C

Can somebody explain to me what happens with br agument in union, after assigning str.a and str.b? We need to set that value before calling the function above? I tried to run the code in simulator https://pythontutor.com/render.html#mode=display which says that the value of br is 516 before calling the function. How is that possible?
#include <stdio.h>
void f(short num, short* res){
if (num){
*res = *res * 10 + num%10;
f(num / 10, res);
}}
typedef union {
short br;
struct {
char a, b;
} str;
} un;
void main() {
short res = 0; un x;
x.str.a = 4; x.str.b = 2;
f(x.br, &res); x.br = res;
printf("%d %d %d\n", x.br, x.str.a, x.str.b);}
Assuming that char is one byte and short is two bytes (the most common), then it's really simple.
Begin by drawing out the members of the union on a piece of paper, one member next to the other. Something like this:
br str
+---+ +---+
| | | | a
+---+ +---+
| | | | b
+---+ +---+
Now we do the assignments:
x.str.a = 4;
x.str.b = 2;
And write the results in the drawing:
br str
+---+ +---+
| 4 | | 4 | a
+---+ +---+
| 2 | | 2 | b
+---+ +---+
Assuming little endianness like on a normal x86 or x86-64 system, then the value of br will be 0x0204 which is 516 in decimal.
So that's where the value 516 is coming from.
The value of the short will depend on the computer's endianess. On a little endian machine, a will correspond to the least significant byte and b to the most significant. Thus when those two bytes are converted to a short, you get the number 0x0204 = 516 decimal.
As a side note, it is a bad idea to use short and char since those may be signed and negative. Use uint16_t and uint8_t instead, whenever dealing with binary arithmetic.
If you put some effort into your debugging you would see what is going on:
void f(short num, short* res)
{
if (num)
{
*res = *res * 10 + num%10;
f(num / 10, res);
}
}
typedef union
{
short br;
struct
{
char a, b;
};
} un;
int main(void)
{
short res = 0; un x;
x.a = 4; x.b = 2;
printf("Before br=0x%04x (%d) a=0x%02x b=0x%02x res = %d 0x%x\n", x.br, x.br, x.a, x.b, res, res);
f(x.br, &res); x.br = res;
printf("After br=0x%04x a=0x%02x b=0x%02x res = %d 0x%x\n", x.br, x.a, x.b, res, res);
}
result:
efore br=0x0204 (516) a=0x04 b=0x02 res = 0 0x0
After br=0x0267 a=0x67 b=0x02 res = 615 0x267
Do your br was 516 and it was reversed by the f function becoming 615 which is 0x0276. It contains of two bytes 0x02 and 0x67.
Your computer is little-endian so the first byte is 0x67 and the second one is 0x02 because this system stores the least significant byte first.

Predict the result after passing the pointer

#include <stdio.h>
int main()
{
int x = 1023;
char *p = (char *)&x;
printf("%d %d %d %d\n", p[0], p[1], p[2], p[3]);
}
The result is: -1 3 0 0
I have imagined:
int x = 1023 (4 bytes):
m m+1 m+2 m+3
-+----+----+----+----+----+----+-
| | 255| 3 | 0 | 0 | |
-+----+----+----+----+----+----+-
~~~~~~~~~~~~~~~~~~~~~
cast to char pointer:
m
-+----+----+----+----+----+----+-
| | 255| 3 | 0 | 0 | |
-+----+----+----+----+----+----+-
~~~~~~
Why is the result -1 3 0 0? Or where did I go wrong?
char can be either signed char or unsigned char, it's implementation-dependent. Your implementation uses signed char. The values range from -128 to 127, 255 is not a possible value. That byte representation corresponds to -1.
Change your pointer declaration to
unsigned char *p = (unsigned char*)&x;
and you'll get the result you expect.

Bitwise Operation on a byte and an int

I have a byte array represented as
char * bytes = getbytes(object); //some api function
I want to check whether the bit at some position x is set.
I've been trying this
int mask = 1 << x % 8;
y= bytes[x>>3] & mask;
However y returns as all zeros? What am I doing incorrectly and is there an easier way to check if a bit is set?
EDIT:
I did run this as well. It didn't return with the expected result either.
int k = x >> 3;
int mask = x % 8;
unsigned char byte = bytes[k];
return (byte & mask);
it failed an assert true ctest I ran. Byte and Mask at this time where "0002" and 2 respectively when printed from gdb.
edit 2: This is how I set the bits in the first place. I'm just trying to write a test to verify they are set.
unsigned long x = somehash(void* a);
unsigned int mask = 1 << (x % 8);
unsigned int location = x >> 3;
char* filter = getData(ref);
filter[location] |= mask;
This would be one (crude perhaps) way from the top of my head:
#include "stdio.h"
#include "stdlib.h"
// this function *changes* the byte array
int getBit(char *b, int bit)
{
int bitToCheck = bit % 8;
b = b + (bitToCheck ? (bit / 8) : (bit / 8 - 1));
if (bitToCheck)
*b = (*b) >> (8 - bitToCheck);
return (*b) & 1;
}
int main(void)
{
char *bytes = calloc(2, 1);
*(bytes + 1)= 5; // writing to the appropiate bits
printf("%d\n", getBit(bytes, 16)); // checking the 16th bit from the left
return 0;
}
Assumptions:
A byte is represented as:
----------------------------------------
| 2^7 | 2^6 | 2^5 | 2^4 | 2^3 |... |
----------------------------------------
The left most bit is considered bit number 1 and the right most bit is considered the max. numbered bit (16th bit in a 2 byte object).
It's OK to overwrite the actual byte object (if this is not wanted, use memcpy).

C converting an int to a bitshift operator

I can only use these symbols:
! ~ & ^ | + << >>
Here is the table I need to achieve:
input | output
--------------
0 | 0
1 | 8
2 | 16
3 | 24
With the output I am going to left shift a 32 bit int over.
Ex.
int main()
{
int myInt = 0xFFFFFFFF;
myInt = (x << (myFunction(2)));
//OUTPUT = 0xFFFF0000
}
int myFunction(int input)
{
// Do some magic conversions here
}
any ideas????
Well, if you want a function with f(0) = 0, f(1) = 8, f(3) = 24 and so on then you'll have to implement f(x) = x * 8. Since 8 is a perfect power of two the multiplication can be replaced by shifting. Thus:
int myFunction(int input)
{
return input << 3;
}
That's all.

Resources