Am I using memcpy wrong? - c

I'm trying to use memcpy to copy part of an unsigned int to another unsigned int within the same struct I made. But my program only prints the first printf statement and then says: Process returned -1073741819 (0xC0000005)
Am I using memcpy wrong?
#include <stdio.h>
#include <string.h>
int main()
{
struct time
{
unsigned int hours:5;
unsigned int minutes:6;
unsigned int seconds:6;
};
struct time t = {0x10,0b101011,45};
printf("The time is : %d:%d:%d\n", t.hours, t.minutes, t.seconds);
memcpy(t.minutes, t.seconds, 2);
printf("The time is : %d:%d:%d\n", t.hours, t.minutes, t.seconds);
return 0;
}
I've already done t.minutes = t.seconds and that copies the whole number, but I only want a portion of it.

In response to your clarification in the comments:
When I say part of number I mean I'm trying to copy the most significant 2 bits of the unsigned int.
The way to copy individual bits is by doing bit manipulation with bitwise operators.
The two most significant bits in your 6-bit fields are therefore represented by the value 0x30 (110000 in binary). To copy these from one to another, simply clear out those bits in the destination, then mask the source and combine with bitwise-OR:
unsigned int mask = 0x30;
t.minutes = (t.minutes & ~mask) | (t.seconds & mask);
Breakdown of the above:
~mask inverts the mask, meaning that bits 4 and 5 will be 0 and all other bits will be 1
this value is then ANDed with minutes, resulting in clearing bits 4 and 5
the opposite occurs when ANDing the mask with seconds, resulting in only bits 4 and 5 being preseved, and all other bits cleared
the two values are then combined with OR and assigned to minutes

Related

Test feedback: oddParitySet3 incorrectly returned

Purpose: Demonstrate the ability to manipulate bits using functions and to learn a little bit about parity bits.
Parity is a type of error detection where one of the bits in a bit string is used for this purpose. There are more complicated systems that can do more robust error detection as well as error correction. In this lab, we will use a simple version called odd parity. This reserves one bit as a parity bit. The other bits are examined, and the parity bit is set so that the number of 1 bits is odd. For example, if you have a 3-bit sequence, 110 and the rightmost bit is the parity bit, it would be set to 1 to make the number of 1s odd.
Notes: When referring to bit positions, bit 31 is the high-order bit (leftmost), and bit 0 is the low-order bit (rightmost). In order to work through these functions, you will likely have to map out bit patterns for testing to see how it all works. You may find using a converter that can convert between binary, hex, and decimal useful. Also, to assign bit patterns to integers, it might be easier to use hex notation. To assign a hex value in C, you can use the 0x????? where ????? are hex values. (There can be more or fewer than the number of ? here.) E.g.,
int i = 0x02A;
Would assign i = 42 in decimal.
Program Specifications: Write the functions below:
unsigned int leftRotate(unsigned int intArg, unsigned int rotAmt);
Returns an unsigned int that is intArg rotated left by rotAmt. Note: Rotate left is similar to shift left. The difference is that the bits shifted out at the left come back in on the right. Rotate is a common operation and often is a single machine instruction. Do not convert intArg to a string and operate on that. Do not use an array of ints (or other numbers). Use only integers or unsigned integers.
Example: Assuming you have 5-bit numbers, rotating the binary number 11000 left by 3 yields 00110
char *bitString(int intArg)
Returns a pointer to a character string containing the 32-bit pattern for the integer argument. The first character, index 0, should be the high-order bit and on down from there. For this function, you will need malloc. Can be used for printing bit patterns. E.g., if intArg = 24 the return string would be 00000000000000000000000000011000
unsigned int oddParitySet3(unsigned int intArg, unsigned int startBit);
This function will determine the odd parity for a 3-bit segment of intArg starting at bit startBit and set the parity bit (low-order bit) appropriately.
E.g., suppose intArg=3 and startBit = 2. The 32 bit representation, from high to low, would be 29 zeros then 110. So, bits 2 - 0 are 011. To make the parity odd, you would set bit zero to 0.
The return value is the modified intArg, in this case it would be 29 zeros then 010 or a value of 2.
Do not convert intArg to a string and operate on that. Use only integers or unsigned integers.
Note: If the start bit is greater than 31 or less than 2, this would present a problem (do you see this?). If this is the case, return a zero.
The compile command used by this zyLab is:
gcc main.c -Wall -Werror -Wextra -Wuninitialized -pedantic-errors -o a.out -lm
The program does not pass all tests and gives such errors:
enter image description here
C code:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char * bitString(int intArg);
unsigned int leftRotate(unsigned int n, unsigned int d);
unsigned int oddParitySet3(unsigned int intArg, unsigned int startBit);
int main() {
return 0;
}
char * bitString(int intArg)
{
char *bits = (char*)malloc(33 * sizeof(char));
bits[32] = '\0';
for(int i = 31; i >= 0; i--)
{
if(intArg & (1 << i))
bits[31 - i] = '1';
else
bits[31 - i] = '0';
}
return bits;
}
unsigned int leftRotate(unsigned int intArg, unsigned int rotAmt)
{
return (intArg << rotAmt) | (intArg >> (32 - rotAmt));
}
unsigned int oddParitySet3(unsigned int intArg, unsigned int startBit){
unsigned int mask = 0x00000007;
unsigned int shiftedMask = mask << startBit;
unsigned int temp = intArg & shiftedMask;
unsigned int result = intArg;
if(__builtin_popcount(temp) % 2 == 0)
result |= shiftedMask;
else
result &= ~shiftedMask;
return result;
}
need help to fix the oddParitySet3 function so that it does not display errors that are in the photo.

bit programing in C [duplicate]

This question already has answers here:
How do I split up a long value (32 bits) into four char variables (8bits) using C?
(6 answers)
Closed 8 months ago.
I am new to bits programming in C and finding it difficult to understand how ipv4_to_bit_string() in below code works.
Can anyone explain that, what is happening when I pass integer 1234 to this function. Why integer is right shifted at 24,16,8 and 4 places?
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct BIT_STRING_s {
uint8_t *buf; /* BIT STRING body */
size_t size; /* Size of the above buffer */
int bits_unused; /* Unused trailing bits in the last octet (0..7) */
} BIT_STRING_t;
BIT_STRING_t tnlAddress;
void ipv4_to_bit_string(int i, BIT_STRING_t *p)
{
do {
(p)->buf = calloc(4, sizeof(uint8_t));
(p)->buf[0] = (i) >> 24 & 0xFF;
(p)->buf[1] = (i) >> 16 & 0xFF;
(p)->buf[2] = (i) >> 8 & 0xFF;
(p)->buf[3] = (i) >> 4 & 0xFF;
(p)->size = 4;
(p)->bits_unused = 0;
} while(0);
}
int main()
{
BIT_STRING_t *p = (BIT_STRING_t*)calloc(1, sizeof(BIT_STRING_t));
ipv4_to_bit_string(1234, p);
}
An IPv4 address is four eight-bit pieces that have been put together into one 32-bit piece. To take the 32-bit piece apart into the four eight-bit pieces, you extract each eight bits separately. To extract one eight-bit piece, you shift right by 0, 8, 16, or 24 bits, according to which piece you want at the moment, and then mask with 0xFF to take only the low eight bits after the shift.
The shift by 4 instead of 0 appears to be an error.
The use of an int for the 32-bit piece appears to be an error, primarily because the high bit may be set, which indicates the int value is negative, and then the right-shift is not fully defined by the C standard; it is implementation-defined. An unsigned type should be used. Additionally, int is not necessarily 32 bits; it is preferable to use uint32_t, which is defined in the <stdint.h> header.

Grabbing 'n' binary bits from end of unsigned int in C? Bit masking?

I'm pretty new to C and I seem to be messing up my bitmasking. From what I understand, it's a way to grab or create something of a subset from a binary value.
Say I want to grab the last 8 bits of an unsigned int value, containing 00001111000011110000111100001111.
How would I use AND/OR to grab those last 8?
Here's a more general solution to generate the mask based on how many bits you're interested int.
unsigned int last_n_bits(unsigned int value, int n)
{
unsigned int mask = -1;
if (n < sizeof(unsigned) * CHAR_BIT)
mask = ((1<<n)-1);
return value & mask;
}
You can use the BINARY AND operator for do a binary mask:
unsigned char last_eight_bits = my_number & 0b11111111
Mask-out all bits > 0xff:
value & 0xffu
Say I want to grab the last 8 bits of an unsigned int value, containing
00001111000011110000111100001111.
How would I use AND/OR to grab those last 8?
In this case, you would use AND. The following code will grab the 8 least significant bits:
unsigned int number = 0x0F0F0F0Fu;
unsigned int mask = 0x000000FFu; // set all bits to "1" which you want to grab
unsigned int result = number & mask; // result will be 0x0000000F
The &-Operator is used for an AND-Operation with each bit:
00001111000011110000111100001111
AND 00000000000000000000000011111111
------------------------------------
00000000000000000000000000001111
Be aware that "0 AND X = 0" and that "1 AND X = X". You can do further investigation at: https://en.wikipedia.org/wiki/Boolean_algebra.

How to handle a bunch of 0s and 1s with a microcontroller?

I'm making a program to receive a bunch of 0's and 1's with a µC and need to take any amount of bits (1 to 16) from any position.
I.E. I have 150 bits and I want to take 6 bits from the 32th bit and copy it to a char (8bits) variable; I know I can do it with strings by saving as ASCII 0's and 1's, but I have not a lot of RAM, so I need to save it as bits.
The bigger variable is a unsigned 32 bits long, but save the data is not my problem, the problem is how to access to a specific bits positions and copy that to a char(8) variable.
You can use bitwise operators:
//bits: your bits (byte array), start: index of the first bit of the char you want
char select(char* bits, int start) {
dec = start%8;
return bits[start/8]>>dec + bits[start/8+1]<<dec;
}
The code above supposed start < (bits.size()-8)
[EDIT]
You can change the char* to any type you want. However you will need to change dec value to the appropriate number of bits (8*SIZE_IN_BYTES) and then apply operator | ("logical or") to get your char back
example:
char select(int* bits, int start) {
nbitsint = 8*4;
dec = start%nbitsint;
if (dec < nbitsint-8) {
// | 0xff creates creates a byte
return (bits[start/nbitsint]>>((3-dec/8)*8+dec%8) | 0xff;
}
// Getting a byte which is astride two values is tricky
return (bits[start/nbitsint]>>(start%8) + bits[start/nbitsint+1]<<(start%8) | 0xff;
}

How to print specific byte of unsigned integer?

I'm attempting to write a program in C that examines bytes in memory and prints their contents. Given a 4-byte unsigned integer, what would a function look like that prints a specific byte of the integer to stdout in hexadecimal? Does printf have some sort of capability like this built-in?
Here's the interface of what I'm looking for.
// number - the integer to be examined
// order - the byte to be examined, with 0 being the lowest-order
// (first) byte and 3 being the highest order (last) byte
void print_byte(unsigned number, unsigned order);
If it's important for the implementation, this would be a little-endian machine.
Please Try This...
#include <stdio.h>
void print_byte(unsigned number, unsigned order)
{
unsigned i = 0;
i = (number >> (8*order)) & 0x000000FF;
printf("Number:0x%08x, Byte:%02x, Order:%d\n",number,i,order);
return;
}
int main(void) {
print_byte(0x1f2e3d4c,0);
print_byte(0x1f2e3d4c,1);
print_byte(0x1f2e3d4c,2);
print_byte(0x1f2e3d4c,3);
return 0;
}
If using C99 or later, use the length modifier "hh" after shifting. This modifier will convert the integer to unsigned/signed char before printing. Use 8 or CHAR_BIT depending on meaning of "byte".
printf("%hhX", number >> (order * 8));
or
#include <limits.h>
printf("%hhX", number >> (order * CHAR_BIT));

Resources