how to cast an int array to a byte array in C - c

hey i would like to know how you could cast an Int array in C to an byte array and what would be the declaration method. I would appreciate if it is simpler and no use of pointers. thanks for the comments
ex: int addr[500] to byte[]
Plus I would also want the ending byte array to have the same array name.

If you are trying to reinterpret the memory behind the int array as an array of bytes, and only then:
int ints[500];
char *bytes = (char *) ints;
You cannot do this without resorting to pointer casting, as declaring a [] array implies allocation on stack, and cannot be used for reinterpretation of existing memory.
Obviously, you need to know what you are doing. For each int there will be (typically, depending on platform etc.) 4 chars, so your new array would have 500*4 elements. Check out what the output of:
printf("char size: %d, int size: %d", sizeof(char), sizeof(int));
tells you to make sure.
If you are trying to interpret each int as a char, i.e. to get the same number of chars, as there were ints, then you cannot do this without a loop and manual conversion (to a new memory locaton, normally).

You can use a union.
union {
int ints[500];
char bytes[0];
} addr;

If you want to
reinterpret the memory behind the int array as bytes,
want to avoid pointers syntactically --for whatever reason--, and
making a copy of the int array is acceptable,
then you could create a new char array and copy the int array with memcpy:
int ints[500];
char bytes[500 * 4];
memcpy(bytes, ints, 500 * 4);
This is about the same as the first snippet from my original answer, with the difference that the bytes contain a copy of the ints (i.e. modifying one doesn't influence the other). Usual caveats about int size and avoiding magic constants/refactoring code apply.

It might be easier to use pointers but without pointers, try the following:
#include <stdio.h>
typedef unsigned char byte;
void main() {
int addr_size = 500;
int addr[ addr_size ];
byte bytes[ addr_size * 4 ];
int i;
for( i = 0; i < addr_size; i++ ) {
bytes[ i ] = (byte)( addr[ i ] >> 24);
bytes[ i + 1 ] = (byte)( addr[ i ] >> 16);
bytes[ i + 2 ] = (byte)( addr[ i ] >> 8);
bytes[ i + 3 ] = (byte)addr[ i ];
}
}

Related

How to extract a pointer size in C

i have code like this:
int main()
{
double *u;
int len;
u=(double *)malloc(sizeof(double)*10);
len = sizeof(u);
printf("Length Of Array = %d\n", len);
return 0;
}
but the length is 4 Not 10.
how can i extract 10 from pointer u?!
please help me
thank you
That's your job. C does not provide a portable way of knowing, given a pointer, how much memory has been allocated.
sizeof will give you sizeof(double*), that's all. That's 4 on your system.
It is not possible. sizeof is giving the size of the object. In your case the object is u which is a pointer. Your system is 32 bits as pointers are 4 bytes.
if you sizeof(*u)- you will get the size of referenced type. In this case it is the double . It will be 8 bytes long at most systems.
using sizeof to get the size of the length of the string is one of the most frequent questions asked here.
A pointer doesn't include information about the size of the memory area. You have to keep track of the size yourself. For instance, you can make a custom type (for example, a struct) that contains both the pointer and the size of the allocation at the same time.
Here's a simple implementation to get you started:
typedef struct {
double* ptr;
size_t len;
} double_arr_t;
// prototype
double_arr_t alloc_double_arr(size_t len);
int main(void) {
// alloc the new array of 10 `double` elements
double_arr_t arr = alloc_double_arr(10);
printf("Length of 'arr' is %zu\n", arr.len); // Length of 'arr' is 10
// assign a value to the first element
arr.ptr[0] = 3.14;
// get the value of the first element
double first_element = arr.ptr[0];
// free the array when you're done using it
free(arr.ptr);
}
double_arr_t alloc_double_arr(size_t len) {
double_arr_t res;
res.ptr = malloc(len * sizeof(double));
res.len = len;
return res;
}

Use array annotation with pointers

I have currently trouble understanding the following scenario:
I have a multidimensional array of Strings and I want to address it by using pointers only but I always get a Segmentation Fault when using the array annotation on the pointer. This is just an example code I want to use the 3D array in a pthread so I want to pass it in via a structure as a pointer but it just doesn't work and I would like to know why? I thought pointers and arrays are functionally equivalent? Here is the sample code:
#include <stdio.h>
void func(unsigned char ***ptr);
int main() {
// Image of dimension 10 times 10
unsigned char image[10][10][3];
unsigned char ***ptr = image;
memcpy(image[0][0], "\120\200\12", 3);
// This works as expected
printf("Test: %s", image[0][0]);
func(image);
return 0;
}
void func(unsigned char ***ptr) {
// But here I get a Segmentation Fault but why??
printf("Ptr: %s", ptr[0][0]);
}
Thanks in advance for your help :)
I think maybe strdup confuses the issue. Pointers and arrays are not always equivalent. Let me try to demonstrate. I always avoid actual multi-dimension arrays, so I may make a mistake here, but:
int main()
{
char d3Array[10][10][4]; //creates a 400-byte contiguous memory area
char ***d3Pointer; //a pointer to a pointer to a pointer to a char.
int i,j;
d3Pointer = malloc(sizeof(char**) * 10);
for (i = 0; i < 10; ++i)
{
d3Pointer[i] = malloc(sizeof(char*) * 10);
for (j = 0; j < 4; ++j)
{
d3Pointer[i][j] = malloc(sizeof(char) * 4);
}
}
//this
d3Pointer[2][3][1] = 'a';
//is equivalent to this
char **d2Pointer = d3Pointer[2];
char *d1Pointer = d2Pointer[3];
d1Pointer[1] = 'a';
d3Array[2][3][1] = 'a';
//is equivalent to
((char *)d3Array)[(2 * 10 * 4) + (3 * 4) + (1)] = 'a';
}
Generally, I use the layered approach. If I want contiguous memory, I handle the math myself..like so:
char *psuedo3dArray = malloc(sizeof(char) * 10 * 10 * 4);
psuedo3dArray[(2 * 10 * 4) + (3 * 4) + (1)] = 'a';
Better yet, I use a collection library like uthash.
Note that properly encapsulating your data makes the actual code incredibly easy to read:
typedef unsigned char byte_t;
typedef struct
{
byte_t r;
byte_t g;
byte_t b;
}pixel_t;
typedef struct
{
int width;
int height;
pixel_t * pixelArray;
}screen_t;
pixel_t *getxyPixel(screen_t *pScreen, int x, int y)
{
return pScreen->pixelArray + (y*pScreen->width) + x;
}
int main()
{
screen_t myScreen;
myScreen.width = 1024;
myScreen.height = 768;
myScreen.pixelArray = (pixel_t*)malloc(sizeof(pixel_t) * myScreen.height * myScreen.width);
getxyPixel(&myScreen, 150, 120)->r = 255;
}
In C, you should allocate space for your 2D array one row at a time. Your definition of test declares a 10 by 10 array of char pointers, so you don't need to call malloc for it. But to store a string you need to allocate space for the string. Your call to strcpy would crash. Use strdup instead. One way to write your code is as follows.
char ***test = NULL;
char *ptr = NULL;
test = malloc(10 * sizeof(char **));
for (int i = 0; i < 10; i++) {
test[i] = malloc(10 * sizeof(char *));
}
test[0][0] = strdup("abc");
ptr = test[0][0];
printf("%s\n", ptr);
test[4][5] = strdup("efg");
ptr = test[4][5];
printf("%s\n", ptr);
Alternatively, if you want to keep your 10 by 10 definition, you could code it like this:
char *test[10][10];
char *ptr = NULL;
test[0][0] = strdup("abc");
ptr = test[0][0];
printf("%s\n", ptr);
test[4][5] = strdup("efg");
ptr = test[4][5];
printf("%s\n", ptr);
Your problem is, that a char[10][10][3] is something very different from a char***: The first is an array of arrays of arrays, the later is a pointer to a pointer to a pointer. The confusions arises because both can be dereferenced with the same syntax. So, here is a bit of an explanation:
The syntax a[b] is nothing but a shorthand for *(a + b): First you perform pointer arithmetic, then you dereference the resulting pointer.
But, how come you can use a[b] when a is an array instead of a pointer? Well, because...
Arrays decay into pointers to their first element: If you have an array declared like int array[10], saying array + 3 results in array decaying to a pointer of type int*.
But, how does that help to evaluate a[b]? Well, because...
Pointer arithmetic takes the size of the target into account: The expression array + 3 triggers a calculation along the lines of (size_t)array + 3*sizeof(*array). In our case, the pointer that results from the array-pointer-decay points to an int, which has a size, say 4 bytes. So, the pointer is incremented by 3*4 bytes. The result is a pointer that points to the fourths int in the array, the first three elements are skipped by the pointer arithmetic.
Note, that this works for arrays of any element type. Arrays can contain bytes, or integers, or floats, or structs, or other arrays. The pointer arithmetic is the same.
But, how does that help us with multidimensional arrays? Well, because...
Multidimensional arrays are just 1D arrays that happen to contain arrays as elements: When you declare an array with char image[256][512]; you are declaring a 1D array of 256 elements. These 256 elements are all arrays of 512 characters, each. Since the sizeof(char) == 1, the size of an element of the outer array is 512*sizeof(char) = 512, and, since we have 256 such arrays, the total size of image is 256*512. Now, I can declare a 3D array with char animation[24][256][512];...
So, going back to your example that uses
char image[10][10][3]
what happens when you say image[1][2][1] is this: The expression is equivalent to this one:
*(*(*(image + 1) + 2) + 3)
image being of type char[10][10][3] decays into a pointer to its first element, which is of type char(*)[10][3] The size of that element is 10*3*1 = 30 bytes.
image + 1: Pointer arithmetic is performed to add 1 to the resulting pointer, which increments it by 30 bytes.
*(image + 1): The pointer is dereferenced, we are now talking directly about the element, which is of type char[10][3].
This array again decays into a pointer to its first element, which is of type char(*)[3]. The size of the element is 3*1 = 3. This pointer points at the same byte in memory as the pointer that resulted from step 2. The only difference is, that it has a different type!
*(image + 1) + 2: Pointer arithmetic is performed to add 2 to the resulting pointer, which increments it by 2*3 = 6 bytes. Together with the increment in step 2, we now have an offset of 36 bytes, total.
*(*(image + 1) + 2): The pointer is dereferenced, we are now talking directly about the element, which is of type char[3].
This array again decays into a pointer to its first element, which is of type char*. The size of the element is now just a single byte. Again, this pointer has the same value as the pointer resulting from step 5, but a different type.
*(*(image + 1) + 2) + 1: Pointer arithmetic again, adding 1*1 = 1 bytes to the total offset, which increases to 37 bytes.
*(*(*(image + 1) + 2) + 1): The pointer is dereferenced the last time, we are now talking about the char at an offset of 37 bytes into the image.
So, what's the difference to a char***? When you dereference a char***, you do not get any array-pointer-decay. When you try to evaluate the expression pointers[1][2][1] with a variable declared as
char*** pointers;
the expression is again equivalent to:
*(*(*(pointers + 1) + 2) + 3)
pointers is a pointer, so no decay happens. Its type is char***, and it points to a value of type char**, which likely has a size of 8 bytes (assuming a 64 bit system).
pointers + 1: Pointer arithmetic is performed to add 1 to the resulting pointer, which increments it by 1*8 = 8 bytes.
*(pointers + 1): The pointer is dereferenced, we are now talking about the pointer value that is found in memory at an offset of 8 bytes of where pointers points.
Further steps depending on what actually happened to be stored at pointers[1]. These steps do not involve any array-pointer-decay, and thus load pointers from memory instead.
You see, the difference between a char[10][10][3] and a char*** is profound. In the first case, the array-pointer-decay transforms the process into a pure offset computation into a multidimensional array. In the later case, we repeatedly load pointers from memory when accessing elements, all we ever have are 1D arrays of pointers. And it's all down to the types of pointers!

How to create many blocks of memory with one reference in C

I am trying to allocate blocks of memory for my program. I need to allocate 8 blocks of memory each having 62500bytes ( sizeof Int * 32 ) . In a way I am allocating 2,000,000 bit for each block (total number of blocks are 8).
I tried using int *a= (int*) calloc(62500 * 8, sizeof(int)) and I use
int i=0;
for (i = 0; i < 62500 * 8; i++) {
blk[i] = i;
}
I use the above to allocate a value to each address so that it is easy to keep track of which index I need to fetch, since unlike array which are consecutive blocks of memory , if I use calloc I do not get consecutive memory addresses. But my problem here is I want each of 8 blocks allocated with a start index as 0 and end as 62500.Like block1(0...62500) , block2(0...62500),block3(0...62500) ... block8(0...62500). I am not sure how to get this kind of structure.
I started with something like:
typedef struct block {
int b;
} blk;
How do I make a struct *blk = {block1,block2,block3...block8}, So that I can reach to each block from pointer *blk.
Thanks
Get a pointer to an array of arrays.
#define BLK_SZ 62500
#define BLK_NMEMB 8
The parentheses here denote that blk is a pointer to an array, rather than an array of pointers.
int (*block)[BLK_SZ][BLK_NMEMB] = calloc(62500 * 8, sizeof(int));
Note that the cast is unnecessary because void * is guaranteed to convert to any other pointer type. Now you can address it like:
(*block)[0][9001] = 14;
You can also create a typedef:
typedef int blk[BLK_SZ][BLK_NMEMB];
Which can then be used as:
blk *block = calloc(BLK_SZ * BLK_NMEMB, sizeof(int));
and addressed in the same manner as above.
If you really must, you can do:
typedef struct {
int block0[BLK_SZ];
int block1[BLK_SZ];
int block2[BLK_SZ];
int block3[BLK_SZ];
int block4[BLK_SZ];
int block5[BLK_SZ];
int block6[BLK_SZ];
int block7[BLK_SZ];
} blk;
and:
blk *block = calloc(BLK_SZ * BLK_NMEMB, sizeof(int));
accesed by
(*block).block0[9001] = 14;

Length of char array (where "int" values are stored)

I need to store the some integer values in the char array with same size of memory .
like int32 should fit in char[4] .
so below is the thing I tried
int val = 123457;
char *data = val;
this stores properly, but If I allocate like this , I can not get the length or free it.
so I tried like this.
char *data = malloc(sizeof(val);
but How do I copy that int value .
Due to some requirement I have to store in the char array and get back int value from the char array.
Yes, you can do this, but it's not wise to mingle your data types like this unless you actually know what you're doing.
This is fraught with peril, as they say.
Still, if you wish to do it, and then copy the data, you can do it like this:
int val = 123457;
char *data = malloc(sizeof(val);
memcpy(data, &val, sizeof(val));
Another way you can do this is by using union(one more useless thing of c++ if you ask me).
union utyp {
int i;
char ch[sizeof(int)];
};
union utyp x;
x.i=324255;
Union is making all of its variables share the same memory space
324255 is 100 11110010 10011111 to binary
so for example the (int)x.ch[2] is 4
memcpy will solve your problem. You do something like this:
int val = 123457;
char data[sizeof int];
memcpy(data, &val, sizeof int);
Just look up man page for memcpy for more details. Basically it copies specified number of bytes from memory pointed to by second argument to that of first argument.
Note about endian-ness: If your machine is little-endian then data above will contain the bytes in reverse byte-order of what your would see if you represented the value 123457 in binary or hex. If you want to see bytes in data in big-endian then you may want use following code:
int val = htonl(123457);
char data[sizeof int];
memcpy(data, &val, sizeof int);
Here htonl converts whatever byte-order your machine is, into network order, i.e. big-endian.
with
int val = 123457;
char *data = val;
you probably meant
int val = 123457;
char *data = (char*)&val; // note the & to give the address of val
now data is pointing to the int, data is not holding the value, just pointing to it.
but if you want to copy the int value to the allocated memory:
char *data = malloc(sizeof(int));
int val = 123457;
memcpy( data, &val, sizeof(int));
now the int value is both stored in data and in val
you can also use a union
typedef union
{
int myint;
char mychars[sizeof(int)];
} u;
...
u myunion;
myunion.myint = 123456;
now you have the value 123456 in the int and you can get the characters by copying from myunion.mychars
You can do it easily using type casts e.g.
char data[8];
uint32_t a,b; // ATTENTION! int can be 64 bit depending on architecture and compiler !
a=12345;
b=678910;
*(uint32_t *)data=a;
*(uint32_t *)(data+4)=b;
// to retrieve the values
uint32_t c=*(uint32_t *)(data+4); // we'll get b
In C Char having the size of 1 word or byte means you can only store one character either a number..!!! While you trying to store a int32 number it is having 6 chars in terms of character. What are you saying it can't be possible with char in C.

is to possible to assign all zero's to all bits for 128 bits?

int main()
{
int* p= (int*)malloc(8);
for(i=0;i<128;i++)
p=0;
}
i want to assign all zero's for all 128 bits. Is the above code is correct? i want clarification. my aim is to allocate 128 bits to one varaible and assigning all zero's to all 128 bits.
No. You simply assign 0 to the pointer itself (so you lose it and leak memory). Use this:
(Edit: as Jim Balter pointed out, it's easy to handle non-8 bit chars:)
int main()
{
unsigned n = (128 + CHAR_BIT - 1) / CHAR_BIT;
unsigned char *p = malloc(n);
for(i = 0; i < n; i++)
p[i] = 0;
}
But this is reinventing the wheel. Why not use the standard function memset()?
int main()
{
unsigned n = (128 + CHAR_BIT - 1) / CHAR_BIT;
unsigned char *p = malloc(n);
memset(p, 0, n);
}
Wow, there's just so much to pick apart on that...
1) you allocate 8 bytes, which is 64 bits
2) you iterate to 128, which would cause a buffer overflow, except that:
3) in your loop you only ever set the first byte allocated to 0
there are two ways to do this:
p = malloc(128/8);
for (i = 0; i < (128/8); i++)
p[i] = 0;
or you can just use the memset(3) function, provided in all POSIX operating systems.
Instead of allocating and clearing it, calloc() would be better I think.
int* p= (int*)malloc(8);
You allocated 8 bytes i.e 8*8 = 64 bits only.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i = 0;
char *p = calloc(16, sizeof(char));
//for Testing
for(i = 0; i < 16; i++)
printf("%d\t", *p++);
return 0;
}
int sometimes allocates 4 bytes depending on the platform. so use char instead:
char* p= (char*)malloc(16);
for(i=0;i<16;i++)
p[i]=0;
You can simply use a memset routine to nullify as many bytes as you nned. It will look like this:
uint8_t* p= (uint8_t*)malloc(16);
memset(p, 0, 16);
Please note, if you want 128 bits (which is 16 bytes) you need to replace 8 to 16.
Updated:
Since sizes of integer types are system dependent, using uint8_t typedef makes you confident the type you are working with is really 8 bits long. This typedef (as well as the ones for other integer types of fixed size) can be found in stdint.h. If using this header is not possible, you can create these typedefs yourself e.g. typedef unsigned char uint8_t is true for most of the systems.
If the code is later ported to a system with different integer sizes, you don't have to worry about the problems with size incompatibility - all you need is simply changing (u)intX_t (u - for unsigned, X - number of bits) typedefs.
The above code will assign 0 to the pointer, not the content.
To initialize the content, use memset:
memset(p, 0x00, 8);
or dereference the pointer:
for(i=0;i<8;i++)
p[i]=0;
Use calloc( ) to allocate and zero.

Resources