Hey guys so I wish to access an array in a sequential order
int get_value_from_array(char* buffer, int byte1, int byte2) {
int i;
int *j;
j = malloc(sizeof(int));
*j= 0;
for(i = 0; i < byte2 - byte1; i++) {
*j += (buffer[byte1+i] << (i*8));
}
return j;
}
I wish to get some value from point1 to point2 starting from point1. Each is 8 bytes so I shifted by 8. And I'm adding it to j and returning it with j. The way I got this array is by using mmap and reading off some fat.dat file. First of all, I am getting really wild values... I don't understand. I dereferenced j by setting its value as 0 and adding the values to j afterwards.
I have also been following this example. I am not allowed to use malloc to solve this question but then I am even more confused. I tried to use this without the pointers but then I would get floating point exception.
Can you please help me how to fix this?
==========EDIT=====================
ok maybe my question was not clear enough =[
int get_value_from_array(char* buffer, int byte1, int byte2) {
int i;
int j = 0;
for(i = 0; i < byte2 - byte1; i++) {
j += (buffer[byte1+i] << (i*8));
}
return j;
}
this was my first attempt to get this thing working but I kept getting floating point exception. I searched up some stuff and found that an alternative way to do this is casting the value into a pointer and dereferenccing it. I've made some attempts but it's not working so great (or at least returning the most random value + sometimes a seg fault). I hope this clarifies what I wish to do.
This may be what you're after.
int get_value_from_array(char* buffer, int byte1, int byte2)
{
int j = 0;
assert(buffer != 0);
assert(byte1 >= 0 && byte2 >= byte1 && (size_t)(byte2 - byte1) < sizeof(int));
for (int i = 0; i < byte2 - byte1; i++)
j += (unsigned char)buffer[byte1+i] << (i*8);
return j;
}
As noted in my comment, you really don't want to allocate int *j for multiple reasons, including "you aren't allowed to use malloc()" and "it leaks memory when misused as in your question".
And, honest, I wrote this code before I saw your update to the question!
The assert() and (unsigned char) cast are the only differences between your original code and this code. I'm not sure how you get a floating point exception out of that. You can get one of those if you divide by zero, but there isn't an obvious division in your code, let alone division by zero.
You should go back to your original code and print all the information out as it runs. Or use a debugger to step through it.
int get_value_from_array(char* buffer, int byte1, int byte2)
{
int j = 0;
printf("-->> %s: %p (%d..%d)\n", __func__, buffer, byte1, byte2);
assert(buffer != 0);
assert(byte1 >= 0 && byte2 >= byte1 && (size_t)(byte2 - byte1) < sizeof(int));
for (int i = 0; i < byte2 - byte1; i++)
{
printf("j0 = 0x%.8X, i = %d, byte = 0x%.2X, "
"add = 0x%.8X, j1 = 0x%.8X\n",
j, i, (unsigned char)buffer[byte1+i],
(unsigned char)buffer[byte1+i] << (i*8),
j + (unsigned char)buffer[byte1+i] << (i*8));
j += (unsigned char)buffer[byte1+i] << (i*8);
}
printf("<<-- %s: 0x%.8X\n", __func__, j);
return j;
}
Note that printing ends with a newline. In C99, __func__ is the name of the function; omit if you have C89/C90, and remove the %s — or replace %s with your function name (or replace __func__ with your function name as a string literal: "get_value_from_array").
Debuggable code written in C89/C90:
int get_value_from_array(char* buffer, int byte1, int byte2)
{
static const char func[] = "get_value_from_array";
int i;
int j = 0;
printf("-->> %s: %p (%d..%d)\n", func, buffer, byte1, byte2);
assert(buffer != 0);
assert(byte1 >= 0 && byte2 >= byte1 && (size_t)(byte2 - byte1) < sizeof(int));
for (i = 0; i < byte2 - byte1; i++)
{
printf("j0 = 0x%.8X, i = %d, byte = 0x%.2X, "
"add = 0x%.8X, j1 = 0x%.8X\n",
j, i, (unsigned char)buffer[byte1+i],
(unsigned char)buffer[byte1+i] << (i*8),
j + (unsigned char)buffer[byte1+i] << (i*8));
j += (unsigned char)buffer[byte1+i] << (i*8);
}
printf("<<-- %s: 0x%.8X\n", func, j);
return j;
}
Related
I'm working with grap.
My graph is a structure like this
typedef struct{
int order; // number of node
int **mat; // matrix graphe
}graphe;
I'm working on school project and I need to build a set of binary's number from 0 to N (where is the order of the graph)
Actually I did this, it's working. When I'm printing the final variable, it displays all declinaison of binary number (000, 001, 010, 011, etc...)
char** construireSousEnsemble(graphe g){
int size = pow(2, g.order);
char** D = (char**)malloc(sizeof(char*)*g.order-1);
for (int i = 0; i < size; i++){
D[i] = (char*)malloc(g.order-1);
char buffer[g.order-1];
char tmp[g.order-1];
char final[g.order-1];
for (int j = g.order-1; j >= 0; j--){
int bin = (i >> j)&1;
sprintf(buffer, "%d", bin);
snprintf(tmp, sizeof(tmp), "%s", buffer);
strcat(final, tmp);
if (j == 0){
strcpy(D[i], final);
//printf("%s\n", D[i]);
//printf("%d | %s\n", i, D[i]);
memset(final, 0, sizeof(final)); // reset the zone
}
}
//printf("\n");
}
return D;
}
But in the main function, when I'm calling the function like this:
char** zones = construireSousEnsemble(g);
But when I'm printing the content with zones, I have this:
So I'm a bit lost.
This example is for a 3 nodes graph. If I have a 4 nodes, the weird symbol increase and I won't have 0001 or 0010 etc.., same with 5 or 6 nodes.
So my question is, why is this happening?
By the way, I'm not confortable with C so maybe I made some mistakes.
Thank you all :)
Here is the solution (posting if for the future)
char ** construireSousEnsemble(graphe g){
int size = pow(2, g.order);
char **D = (char **) malloc (sizeof (char *) * size);
char buffer[g.order];
char final[g.order];
for (int i = 0; i < size; i++) {
D[i] = (char *)malloc(g.order + 1);
final[0] = 0;
for (int j = g.order - 1; j >= 0; j--) {
int bin = (i >> j) & 1;
sprintf (buffer, "%d", bin);
strcat (final, buffer);
}
strcpy (D[i], final);
}
return D;
}
I'm learning how numbers are represented in memory. I want to know how to print the actual representation (binary or hexadecimal) in memory of some int and float variables.
I'd like to see what happens with that numbers when adding or subtracting it causes overflow, for example.
How can I access memory and print it?
You would need to assign a pointer to the variable in question to a char *, and treat it as an array of bytes of length sizeof(variable). Then you can print each byte in hex using the %X format specifier to printf.
You can define a function like this:
void print_bytes(void *ptr, int size)
{
unsigned char *p = ptr;
int i;
for (i=0; i<size; i++) {
printf("%02hhX ", p[i]);
}
printf("\n");
}
And call it like this:
int x = 123456;
double y = 3.14;
print_bytes(&x, sizeof(x));
print_bytes(&y, sizeof(y));
... to print the actual representation (binary ...
To convert any variable/object to a string that encodes the binary form uses a helper function that converts memory into a "binary" string. This method also handles function pointers. Uses C99 or later.
#include <stdio.h>
#include <assert.h>
#include <limits.h>
// .... compound literal .......
#define VAR_TO_STR_BIN(x) obj_to_bin((char [sizeof(x)*CHAR_BIT + 1]){""}, &(x), sizeof (x))
char *obj_to_bin(char *dest, void *object, size_t osize) {
const unsigned char *p = (const unsigned char *) object;
p += osize;
char *s = dest;
while (osize-- > 0) {
p--;
unsigned i = CHAR_BIT;
while (i-- > 0) {
*s++ = ((*p >> i) & 1) + '0';
}
}
*s = '\0';
return dest;
}
int main(void) {
int i = 42;
double d = 3.1415926535897932384626433832795;
printf("Sample\ndouble pi:%s\nint 42:%s\n", VAR_TO_STR_BIN(d), VAR_TO_STR_BIN(i) );
return 0;
}
Output (Note: depending in endian-ness, results may vary)
Sample
double pi:0100000000001001001000011111101101010100010001000010110100011000
int 42:00000000000000000000000000101010
This approach is easy to adapt to hexadecimal form.
Let's say you have a int variable called memory. Make sure you see how many bits it is; for many processors an int is 32 bits as well as a memory address. So you need to loop through each bit, like this:
unsigned int memory = 1234;
for (int i = 0; i < 32; i++)
{
printf("%d ", memory >> i & 1);
}
This simple method ORs each bit with 1 and shifts each bit by 1.
#include <stdio.h>
#include <stdlib.h>
void print_bits ( void* buf, size_t size_in_bytes )
{
char* ptr = (char*)buf;
for (size_t i = 0; i < size_in_bytes; i++) {
for (short j = 7; j >= 0; j--) {
printf("%d", (ptr[i] >> j) & 1);
}
printf(" ");
}
printf("\n");
}
int main ( void )
{
size_t n;
scanf("%d", &n);
print_bits(&n, sizeof(n));
return 0;
}
This prints bits of the specified object (n here) with the specified size (in bytes).
#dbush, #Anton, I mixed your codes. It's okay?
#include <stdio.h>
#include <stdlib.h>
void print_bytes( void *ptr, size_t size ) ;
int main( void )
{
int x = 123456 ;
double y = 3.14 ;
print_bytes( &x, sizeof(x) ) ;
print_bytes( &y, sizeof(y) ) ;
return 0 ;
}
void print_bytes( void *ptr, size_t size )
{
//char *buf = (char*) ptr;
unsigned char *p = ptr ;
for( size_t i = 0; i < size; i++ )
{
printf( "%02hhX ", p[i] ) ;
}
printf( "\n" ) ;
for( size_t i = 0; i < size; i++ )
{
for( short j = 7; j >= 0; j-- )
{
printf( "%d", ( p[i] >> j ) & 1 ) ;
}
printf(" ");
}
printf("\n");
}
Call print_bits(memory address of variable, size of variable in byte).
void print_bits(void *ptr, int size) //ptr = memory address of variable, size = size of variable in byte
{
long long *ch = ptr;
int size_bits = size * 8;
for(int i = size_bits-1; i>=0; i--){
printf("%lld", *ch >> i & 1) ;
}
}
It has been tested successfully, working with any variable of less than or equal to 64 bits. This will probably work correctly with variables with other sizes (Not Tested).
Calling:
double d = -7.92282286274e+28;
print_bits(&d, sizeof(d));
Output:
1100010111110000000000000000000011100000000000000000000100010111
I am attempting to write C functions with these two prototypes:
int extract_little (char* str, int ofset, int n);
int extract_big(char* str, int ofset, int n);
Now the general idea is I need to return a n byte integer in both formats starting from address str + ofset. P.S. Ofset doesn't do anything yet, I plan on (trying) to shuffle the memory via an offset once I figure out the little endian, for the big.
I'v trying to get it to output like this; for little endian, based off of i=0xf261a3bf;,
0xbf 0xa3 0x61 0xf2
int main()
{
int i = 0xf261a3bf;
int ofset = 1; // This isn't actually doing anything yet
int z;
for (z = 0; z < sizeof(i); z++){
printf("%x\n",extract_little((char *)&i,ofset, sizeof(i)));
}
return 0;
}
int extract_little(char *str,int offs, int n) {
int x;
for (x = 0; x < n; x++){
return str[x];
}
}
I'm not sure what else to try. I figured out the hard way that even thought I put it in a for loop I still can't return more than 1 value from the return.
Thanks!
unsigned long extract_little(const void *p, size_t offset, unsigned char n) {
unsigned long ret = 0;
for(size_t i = offset + n - 1; i >= offset; i--)
ret = (ret<<8) + ((char *)p)[i];
return ret;
}
unsigned long extract_big(const void *p, size_t offset, unsigned char n) {
unsigned long ret = 0;
for(size_t i = offset; i < (offset + n); i++)
ret = (ret<<8) + ((char *)p)[i];
return ret;
}
int main()
{
int i = 0xf261a3bf;
printf("%x\n", extract_little(&i, 0, sizeof(i)));
return 0;
}
Works (of course) only with n´s which are sizeof(unigned long) maximal.
And can be speed-improved, probably (depending on the compiler optimization).
With respect to your code: return does what it says, it returns from the function. The loop is never run for more than the first element.
With respect to the problem: Check out htonl and ntolh, except for exercise.
I need a logic to acheive my target. I've buffer array size of 38400. This array data can be filled by a controller. Here i have to obtain an AES algorithm. In that i've to read 16 bytes of data from the buffer then encrypt, upto end of buffer. How to spilt an array into 16 bytes and encrypt? . I used following logic but i can't get it right now ?
unsigned char ptext[16] = "Attack at dawn!";
unsigned char ctext[16];
unsigned char decptext[16];
unsigned char buffer[120*160*2];
for (int count = 0; count < 120*160*2; count ++)
buffer[count] = count + 1;
for (i = 0; i < 120*160*2; i ++)
{
ptext[i]= buffer[i];
if(i%15 == 0)
{
aes_encrypt(ctx, ptext, ctext);
for(k = 0; k<=i; k++)
{
ptext[k]='\0';
}
}
}
void aes_encrypt(aes_ctx_t *ctx, unsigned char input[16], unsigned char output[16])
{
int i;
// copy input to state
for(i = 0; i < 16; i++)
ctx->state[i & 0x03][i >> 2] = input[i];
aes_addroundkey(ctx, 0);
for(i = 1; i < ctx->rounds; i++) {
aes_subbytes(ctx);
aes_shiftrows(ctx);
aes_mixcolumns(ctx);
aes_addroundkey(ctx, i);
}
aes_subbytes(ctx);
aes_shiftrows(ctx);
aes_addroundkey(ctx, ctx->rounds);
// copy state to output
for(i = 0; i < 16; i++)
{
output[i] = ctx->state[i & 0x03][i >> 2];
printf("%c",output[i]);
}
}
Note: I've filled buffer[] with random numbers.
Me only have to know how to split an array.
Thanks in Advance.
You don't need to "split" the array (whatever "split" means for you.) Just operate on every 16-byte segment of it:
void process_segment(unsigned char segment[])
{
// Work on the first 16 bytes of 'segment'.
}
// ...
unsigned char buffer[120*160*2];
for (size_t i = 0; i < 120*160*2; i += 16) {
process_segment(buffer + i);
}
The above is just an example. If you want a nested for loop instead, you'd do something like this:
unsigned char buffer[120*160*2];
for (size_t i = 0; i < 120*160*2; i += 16) {
unsigned char* segment = buffer + i;
// Work on the first 16 bytes of 'segment'.
for (size_t j = 0; j < 16; ++j) {
// Work on segment[j].
}
}
You should probably change your aes_encrypt() function to take an unsigned char input[] instead of an unsigned char input[16] so that you can pass segment to it.
The code you posted would then become something like this:
unsigned char ptext[16] = "Attack at dawn!";
unsigned char ctext[16];
unsigned char decptext[16];
unsigned char buffer[120*160*2];
for (int count = 0; count < 120*160*2; count++)
buffer[count] = count + 1;
for (i = 0; i < 120*160*2; i += 16) {
unsigned char *segment = buffer + i;
aes_encrypt(ctx, segment, ctext);
// Clear the current 16-byte segment.
memset(segment, '\0', 16);
// ctext now contains the encrypted data of the current
// 16-byte segment. I assume you want to save it somewhere
// now since it will be overridden in the next iteration of
// the loop.
}
And the signature of your aes_encrypt() function would become:
void aes_encrypt(aes_ctx_t *ctx, unsigned char input[],
unsigned char output[16])
Let's say I'm given a void* memory address and I need to print the bits located in this memory address. How can I do this?
In my processor memory addresses are 32bits as are memory values, also int are 32 bits.
So I thought of doing this:
unsigned int value = *memory_address;
and then by simple arithmetic (some mod and div operations) to get the bits of the value saved in memory_address.
For example value mod 2 will give last bit of this value and so on. But from what I can tell (I was expecting different bits) it doesn't work. Any ideas why?
Also, is anyone aware of ready C source code that "does" such this, reads/writes bits from memory?
Shift the value by one for each bit and or it with 1
unsigned int value = *((unsigned int*)memory_address);
for( int i = 0; i < 32; i++)
{
printf("%d ", value >> i & 1);
}
You can also do it with math operators. You have to get the bit value (2 to the power of the bit index) and substract that value at each iteration to make sure the modulo doesn't return values that we seen before:
for( int i = 0; i < 32; i++)
{
int bit_value = (int)pow(2,i + 1);
int num_bit_value = value % bit_value;
printf("%d ", num_bit_value ? 1 : 0 );
value -= num_bit_value;
}
int main() {
int a = 0xFFFF;
void * v = &a; // v points to a
int * aPtr = (int *) v; // aPtr also points to a
int b = *aPtr; // b gets the value aPtr points to, aka a or 0xFFFF
int aBit = (b >> 3) & 1; // aBit now contains bit 3 of the original a value
// toggle the bit
if (aBit) {
b &= ~(1 << 3); // set bit 3 to 0
} else {
b |= (1 << 3); // set bit 3 to 1
}
*aPtr = b; // update original a
}
I found it easier to think of the memory as a continuous string of characters rather than a void pointer. This way you can address as many bits as you want.
Here is how I have done it.
unsigned char
get_bit(char *array, int bit)
{
int byte, k;
byte = bit/8;
k = 7 - bit % 8;
return array[byte] & (1 << k);
}
void
set_bit(char *array, int bit, unsigned char value)
{
int byte, k;
byte = bit/8;
k = 7 - bit % 8;
if (value)
array[byte] |= (1 << k);
else
array[byte] &= ~(1 << k);
}
How about:
bool isBit4Set = ((*someAddress) & 0x8 != 0);
(*someAddress) |= 0x8; // Set bit 4
Generic solution for printing bytes and bits.
void dump_data(const void *object, size_t size)
{
int i;
printf("[ \n");
for(i = 0; i < size; i++)
{
if (i%4 ==0)
{
printf("#%02X",&((const unsigned char *) object)[i]);
printf("[ ");
}
printf("%02x ", ((const unsigned char *) object)[i] & 0xff);
if ((i+1)%4 == 0)
printf("]\n");
}
printf("]\n");
printf("BINARY FORMAT\n");
for (i = 0; i < size; i++)
{
printf("#%02X",&((const unsigned char *) object)[i]);
printf("[ ");
unsigned char value = (((unsigned char*)object)[i]);
for(int j=0; j<8; j++)
printf("%d ", (value & (0x80 >> j)) ? 1 : 0); // right shifting the value will print bits in reverse.
printf("]\n");
}
}
bool getBit(void* data,int bit){ return ((*((int*)data)) & 1<<bit); }
void setBit(void* data,int bit,bool set){ if(set){ (*((int*)data)) |= 1<<bit; }else{ (*((int*)data)) &= ~(1<<bit); } }
for simple usage