C, memset a double array failed - c

I want to declare a double type array dynamically, so here is my code
void function(int length, ...)
{
...
double *a = malloc(sizeof(double) * length);
memset(a, 1, sizeof(double) * length);
for (int i = 0; i < length; i++)
{
printf("%f", a[i]);
}
...
}
When I pass a length of 2, the code does not print all 1s. It just prints the following:
7.7486e-304
7.7486e-304
So, what should I do to fix it?

memset sets bytes. You're trying to set doubles. Just loop from 0 to length and set each one to 1.0:
for (int i = 0; i < length; i ++)
{
a[i] = 1; // or 1.0 if you want to be explicit
}

You are confusing setting an array and setting the underlying memory that stores an array.
A double is made up of 8 bytes. You are setting each byte that makes up the double to 1.
If you want to initialise each element of the array to 1.0 then you can use a for(;;) loop or since you do seem to be using C++ you can use a container and use a constructor to initialise each element (if the constructor has the ability) or use an algorithm to achieve the same effect.

memset sets every byte of your array to 1 not every int or double element.
You are trying to set double values (maybe 8 or more bytes.) Your approach will only work for the number 0.0 as it happens to be represented with all bytes 0 on systems that use IEEE-754 floating point formats. Note that this would be non portable as the C Standard allows other representations for floating point values.
If a was pointing to an array of integers, your approach would work for 0 and -1 and some special values such as 0x01010101... But it would still be a non portable approach as it would fail or even invoke undefined behavior on exotic architectures with padding bits or non 2s complement integer representation.
The correct way to initialize the array is an explicit loop like this:
for (int i = 0; i < length; i++) {
a[i] = 1.0;
}
The compiler will likely compile this loop into very efficient code.

memset sets 1 byte at a time. Because of that, I recommend that you use a custom function to set an array of any data type to a valid value like the following:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void *g_memset(void *dst, void *val, size_t valSize, size_t count);
int main(void)
{
double x = 1.0;
double Array[50];
g_memset(Array, &x, sizeof(x), 20); /* set the 1st 20 elements to 1.0 */
for (int n = 0; n < 20; n++) {
printf("%.1lf ", Array[n]);
}
putchar('\n');
return 0;
}
void *g_memset(void *dst, void *val, size_t valSize, size_t count)
{
char *ptr = (char *)dst;
while (count-- > 0) {
memcpy(ptr, val, valSize);
ptr += valSize;
}
return dst;
}

You use memset to set your every bytes of array a.Double variable are 8 bytes,after memset array a every bytes is 1.
Function memset is for char array.
If you want init your array a you can use a loop(while/for).
int j;
for(j = 0;i < length;j++)
a[j] = 1;

Related

How to return an array from function A and then function B takes this array

I have two functions in my main function.
I've tried to accomplish this problem with pointers, but as a beginner, it is very complicated to work with this.
int main(){
int *p;
p = function_A();
function_B(p);
return 0;
}
int function_A(){
static int myArray[3];
myArray[0] = 11;
myArray[1] = 22;
myArray[2] = 33;
return myArray;
}
int function_B(int *myPointer){
// Here I just want to print my array I've got from function_A() to the
// console
printf("%d", *myPointer)
return 0;
}
function_A should return a array and function_B should take this array.
Thanks!
There are some issues your compiler will already have told you.
First, you should define the functions before calling them, or at least forward declare them.
Second, to return an array, you need to return a pointer to the first element of this array, i.e. return type is int * and not int.
Third, as FredK pointed out, when you receive just a pointer, you have no chance to determine how many elements are in the array it points to. You can either terminate the array with a specific value, e.g. 0, or you need to return the size of the array, too.
See the following adaptions made to your program:
int* function_A(int *size){
static int myArray[3];
myArray[0] = 11;
myArray[1] = 22;
myArray[2] = 33;
if (size) {
*size = 3;
}
return myArray;
}
void function_B(int *myPointer, int size){
for (int i=0; i<size; i++) {
printf("%d\n", myPointer[i]);
}
}
int main(){
int *p;
int size=0;
p = function_A(&size);
function_B(p,size);
return 0;
}
Note: a reference to an array degrades to the address of the first byte of the array.
the following proposed code:
cleanly compiles
incorporates the comments to the question
assumes the programmer already knows the size of the array
performs the desired functionality
appended '\n' to format string of calls to printf() so output on separate lines
and now, the proposed code:
#include <stdio.h>
int * function_A( void );
void function_B(int *myPointer);
int main( void )
{
int *p;
p = function_A();
function_B(p);
return 0;
}
int * function_A()
{
static int myArray[3];
myArray[0] = 11;
myArray[1] = 22;
myArray[2] = 33;
return myArray;
}
void function_B(int *myPointer)
{
printf("%d\n", myPointer[0]);
printf("%d\n", myPointer[1]);
printf("%d\n", myPointer[2]);
}
a run of the program produces the following output:
11
22
33
Let's say you have a function that creates an array of ints:
int *create_int_array(const size_t num)
{
int *iarray;
size_t i;
if (num < 1)
return NULL; /* Let's not return an empty array. */
iarray = malloc(num * sizeof iarray[0]);
if (!iarray)
return NULL; /* Out of memory! */
/* Fill in the array with increasing integers. */
for (i = 0; i < num; i++)
iarray[i] = i + 1;
return iarray;
}
Let's say tou have a function that calculates the sum of the integers in the array. If we ignore any overflow issues, it could look like this:
int sum_int_array(const int *iarray, const size_t num)
{
int sum = 0;
size_t i;
/* Sum of an empty array is 0. */
if (num < 1)
return 0;
for (i = 0; i < num; i++)
sum += iarray[i];
return sum;
}
Note that sizeof is not a function, but a C language keyword. Its argument is only examined for its size. Thus, sizeof iarray[0] yields the size of each element in iarray, and is completely safe and valid even if iarray is undefined or NULL at that point. You see that idiom a lot in C programs; learn to read it as "size of first element of iarray", which is the same as "size of each element in iarray", because all C array elements have the exact same size.
In your main(), you could call them thus:
#ifndef NUM
#define NUM 5
#endif
int main(void)
{
int *array, result;
array = create_int_array(NUM);
if (!array) {
fprintf(stderr, "Out of memory!\n");
exit(EXIT_FAILURE);
}
result = sum_int_array(array, NUM);
printf("Sum is %d.\n", result);
free(array);
return EXIT_SUCCESS;
}
As you can see, there is really not much to it. Well, you do need to get familiar with the pointer syntax.
(The rule I like to point out is that when reading pointer types, read the specifiers from right to left, delimited by * read as a pointer to. Thus, int *const a reads as "a is a const, a pointer to int", and const char **b reads as "b is a pointer to a pointer to const char".)
In this kind of situations, a structure describing an array makes much more sense. For example:
typedef struct {
size_t max; /* Maximum number of elements val[] can hold */
size_t num; /* Number of elements in val[] */
int *val;
} iarray;
#define IARRAY_INIT { 0, 0, NULL }
The idea is that you can declare a variable of iarray type just as you would any other variable; but you also initialize those to an empty array using the IARRAY_INIT macro. In other words, thus:
iarray my_array = IARRAY_INIT;
With that initialization, the structure is always initialized to a known state, and we don't need a separate initialization function. We really only need a couple of helper functions:
static inline void iarray_free(iarray *array)
{
if (array) {
free(array->val);
array->max = 0;
array->num = 0;
array->val = NULL;
}
}
/* Try to grow the array dynamically.
Returns the number of elements that can be added right now. */
static inline size_t iarray_need(iarray *array, const size_t more)
{
if (!array)
return 0;
if (array->num + more > array->max) {
size_t max = array->num + more;
void *val;
/* Optional: Growth policy. Instead of allocating exactly
as much memory as needed, we allocate more,
in the hopes that this reduces the number of
realloc() calls, which tend to be a bit slow.
However, we don't want to waste too much
memory by allocating and then not using it. */
if (max < 16) {
/* Always allocate at least 16 elements, */
max = 16;
} else
if (max < 65536) {
/* up to 65535 elements add 50% extra, */
max = (3*max) / 2;
} else {
/* then round up to next multiple of 65536, less 16. */
max = (max | 65535) + 65521;
}
val = realloc(array->val, max * sizeof array->val[0]);
if (!val) {
/* We cannot grow the array. However, the old
array is still intact; realloc() does not
free it if it fails. */
return array->max - array->num;
}
/* Note: the new elements in array->val,
array->val[array->max] to
array->val[max-1], inclusive,
are undefined. That is fine, usually,
but might be important in some special
cases like resizing hash tables or such. */
array->max = max;
array->val = val;
}
return array->max - array->num;
}
/* Optional; same as initializing the variable to IARRAY_INIT. */
static inline void iarray_init(iarray *array)
{
array->max = 0;
array->num = 0;
array->val = NULL;
}
The static inline bit means that the functions are only visible in this compilation unit, and the compiler is free to implement the function directly at the call site. Basically, static inline is used for macro-like functions and accessor functions. If you put the structure in a header file (.h), you'd put the related static inline helper functions in it as well.
The growth policy part is only an example. If you omit the growth policy, and always reallocate to array->num + more elements, your code will call realloc() very often, potentially for every int appended. In most cases, doing it that often will slow down your program, because realloc() (as well as malloc(), calloc()) is kind-of slow. To avoid that, we prefer to pad or round up the allocation a bit: not too much to waste allocated but unused memory, but enough to keep the overall program fast, and not bottlenecked on too many realloc() calls.
A "good growth policy" is very much up to debate, and really depends on the task at hand. The above one should work really well on all current operating systems on desktop machines, laptops, and tablets, when the program needs only one or only a handful of such arrays.
(If a program uses many such arrays, it might implement an iarray_optimize() function, that reallocates the array to exactly the number of elements it has. Whenever an array is unlikely to change size soon, calling that function will ensure not too much memory is sitting unused but allocated in the arrays.)
Let's look at an example function that uses the above. Say, the obvious one: appending an integer to the array:
/* Append an int to the array.
Returns 0 if success, nonzero if an error occurs.
*/
int iarray_append(iarray *array, int value)
{
if (!array)
return -1; /* NULL array specified! */
if (iarray_need(array, 1) < 1)
return -2; /* Not enough memory to grow the array. */
array->val[array->num++] = value;
return 0;
}
Another example function would be one that sorts the ints in an array by ascending or descending value:
static int cmp_int_ascending(const void *ptr1, const void *ptr2)
{
const int val1 = *(const int *)ptr1;
const int val2 = *(const int *)ptr2;
return (val1 < val2) ? -1 :
(val1 > val2) ? +1 : 0;
}
static int cmp_int_descending(const void *ptr1, const void *ptr2)
{
const int val1 = *(const int *)ptr1;
const int val2 = *(const int *)ptr2;
return (val1 < val2) ? +1 :
(val1 > val2) ? -1 : 0;
}
static void iarray_sort(iarray *array, int direction)
{
if (array && array->num > 1) {
if (direction > 0)
qsort(array->val, array->num, sizeof array->val[0],
cmp_int_ascending);
else
if (direction < 0)
qsort(array->val, array->num, sizeof array->val[0],
cmp_int_descending);
}
}
Many new programmers do not realize that the standard C library has that nifty and quite efficient qsort() function for sorting arrays; all it needs is a comparison function. If the direction is positive for iarray_sort(), the array is sorted in ascending order, smallest int first; if direction is negative, then in descending order, largest int first.
A simple example main() that reads in all valid ints from standard input, sorts them, and prints them in ascending order (increasing value):
int main(void)
{
iarray array = IARRAY_INIT;
int value;
size_t i;
while (scanf(" %d", &value) == 1)
if (iarray_append(&array, value)) {
fprintf(stderr, "Out of memory.\n");
exit(EXIT_FAILURE);
}
iarray_sort(&array, +1); /* sort by increasing value */
for (i = 0; i < array.num; i++)
printf("%d\n", array.val[i]);
iarray_free(&array);
return EXIT_SUCCESS;
}
If size of array is indeed 3 (or other small fixed value), then you can simply use structs as values, something like:
struct ints3 {
int values[3];
// if needed, can add other fields
}
int main(){
struct ints3 ints;
ints = function_A();
function_B(&ints);
return 0;
}
// note about function_A signature: void is important,
// because in C empty () means function can take any arguments...
struct ints3 function_A(void) {
// use C designated initialiser syntax to create struct value,
// and return it directly
return (struct ints3){ .values = { 11, 22, 33 } };
}
int function_B(const struct ints3 *ints) {
// pass struct as const pointer to avoid copy,
// though difference to just passing a value in this case is insignificant
// could use for loop, see other answers, but it's just 3 values, so:
printf("%d %d %d\n", ints->values[0], ints->values[1], ints->values[2]);
return 0; // does this function really need return value?
}

Segmentation fault when passing 2D array to function

I'm trying to write the values from the string that is read from stdin directly into the array, but I get a segmentation fault. Being that the array is declared after I read N and M, the memory should already be allocated, right?
int main()
{
long long N;
long long M;
scanf("%lld%lld",&N,&M);
char line[M];
long long map[N][M];
for (long long i=0; i<M; i++)
{
scanf("%s", &line);
buildMap(&map, i, &line);
}
for (long long i=0; i<N; i++)
for (long long j=0; j<M; j++)
printf(&map);
}
void buildMap(long long **map, long long i, char * line)
{
for (long long j=0; j<strlen(line); j++)
{
map[i][j] = line[j]-'0';
}
I have read your codes, and I assume you are attempting to build a 2D map via user input, which is a string (named "Line" in your code) that should only contains numbers from 0 to 9. Numbers from 0 to 9 may represent different elements of the map. Am I guessing right?
I copied and modified your code, and finally I managed to get a result like this:
program screenshot
If I am guessing right, let me first explain the reasons why your code can not be successfully complied.
long long M; char line[M];
In here you have used a variable to declare the size of an array. This syntax works in some other programming languages, but not in C. In C, when compling the source code, the compiler must know exactly how much stack memory space to allocate for each function (main() function in your case). Since the complier does not know how large the array is when it is trying to complie your code, you get a compling failure.
One common solution is that, instead of storing array in stack, we choose to store array in heap, because the heap memory is dynamically allocated and released when the program is running. In other words, you can decide how much memory to allocate after you get the user input. Function malloc() and free() are used for this kind of operation.
Another problem is using "long long **map". Though it will not cause complie failure, it won't give you the expected result either. When the M (array width) of the array is a known constant value, we always perfer using "long long map[][M]" as the parameter. However, in your case, with M being unkown, the common solution is to manually calculate the target location, since the elements in an array are always stored in a linear order in memory, regardless of the array demension.
I have fixed the aforementioned two problems, and I am pasting the modified source code below, which has been successfully complied:
#include <malloc.h>
#include <string.h>
void buildMap(int *map, int i, char * line);
int main()
{
int N;
int M;
scanf("%d%d", &N, &M);
/*Since M (available memory space for "Line") is set by user, we need to build
"szSafeFormat" to restrict the user's input when typing the "Line". Assuming M
is set to 8, then "szSafeFormat" will look like "%7s". With the help of
"szSafeFormat", the scanf function will be scanf("%7s", Line), ignoring
characters after offset 7.*/
char szSafeFormat[256] = { 0 };
sprintf(szSafeFormat, "%%%ds", M - 1);
//char line[M];
char *Line = (char *)malloc(sizeof(char) * M); //raw user input
char *pszValidInput = (char *)malloc(sizeof(char) * M); //pure numbers
//long long map[N][M];
int *pnMap = (int *)malloc(sizeof(int) * M * N);
memset(pnMap, 0xFF, M * N * sizeof(int)); //initialize the Map with 0xFF
for (int i = 0; i < /*M*/N; i++)
{
scanf(szSafeFormat, Line); //get raw user input
sscanf(Line, "%[0-9]", pszValidInput); //only accept the numbers
while (getchar() != '\n'); //empty the stdin buffer
buildMap((int *)(pnMap + i * M), i, pszValidInput);
}
printf("\r\n\r\n");
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++)
{
//if the memory content is not 0xFF (means it's a valid value), then print
if (*(pnMap + i * M + j) != 0xFFFFFFFF)
{
printf("%d", *(pnMap + i * M + j));
}
}
printf("\r\n");
}
free(Line);
free(pszValidInput);
free(pnMap);
return 0;
}
void buildMap(int *map, int i, char * line)
{
for (int j = 0; j < strlen(line); j++)
{
(int) *((int *)map + j) = line[j] - '0';
}
}
I used type "int" instead of "long long", but there should not be any problems if you insist to continue using "long long". If you continue to use "long long", the condition while printing out the array values should be changed from:
if (*(pnMap + i * M + j) != 0xFFFFFFFF)
to
if (*(pnMap + i * M + j) != 0xFFFFFFFFFFFFFFFF)
There are also some other modifications regarding user input validation, with which I have written some addtional comments in the code.
Remember that C supports variable-length arrays (something which you already use). That means you can actually pass the dimensions as arguments to the function and use them in the declaration of the array argument. Perhaps something like
void buildMap(const size_t N, const size_t M, long long map[N][M], long long i, char * line) { ... }
Call like
buildMap(N, M, map, i, line);
Note that I have changed the type of N and M to size_t, which is the correct type to use for variable-length array dimensions. You should update the variable-declarations accordingly as well as use "%zu for the scanf format string.
Note that in the call to buildMap I don't use the address-of operator for the arrays. That's because arrays naturally decays to pointers to their first element. Passing e.g. &line is semantically incorrect as it would pass something of type char (*)[M] to the function, not a char *.

C - How would I extract Even numbers from an array and place them into another array called EvenNumbers?

I'm tasked with writing a function that will identify all the even numbers in an sample array {10,2,9,3,1,98,8] and place them in an array called EvenNumbers. I have to allow the function so that it works with different combinations of numbers in the array not just the numbers in the sample array above.
I'm wondering is there any way to add numbers to an array that could be different every time? How would I extract the even numbers an place them into an array? Also
for the even array size its giving me an error that the expression must have a constant value but when I use const int it still gives me that error.
Here is the full question.
"Using the array of sample values {10,2,9,3,1,98,8}, write a function that will identify all the even numbers in an array and place it in an array called EvenNumbers. The function must work in all cases, not just in the case of the array shown. Assume that the array size is always available through a global constant called MAX"
Here is what I have so far. I've no idea how I will extract the even numbers from a for loop and place them in an array. I also dont know what the "expression must have a constant value" is about?
#include <stdio.h>
#include <stdlib.h>
void EvenNumber(int Array[], int size);
int main()
{
int array[7] = { 10,2,9,3,1,98,8 };
EvenNumber(array, 7);
}
void EvenNumber(int Array[], int size)
{
int i;
int EvenArraySize;
for (i = 0; i < size; i++)
{
if (Array[i] % 2 == 0)
{
EvenArraySize++;
}
}
int Even[EvenArraySize];
}
The right way to go is to use malloc to allocate just the right amount of memory.
Count the number of even numbers
Allocate the space needed to store them
Copy even numbers in this space
Do whatever you want with these numbers
Free the allocated space
Snippet:
#include <stdio.h>
#include <stdlib.h>
#define MAX 7
int
main()
{
int array[] = {10,2,9,3,1,98,8};
int *even_numbers;
int i, nb_even_numbers;
for (i = 0, nb_even_numbers = 0; i < MAX; i++)
{
if (array[i] % 2 == 0)
nb_even_numbers++;
}
even_numbers = malloc(sizeof(int) * nb_even_numbers);
if (!even_numbers)
{
perror("malloc");
return 1;
}
for (i = 0, nb_even_numbers = 0; i < MAX; i++)
{
if (array[i] % 2 == 0)
even_numbers[nb_even_numbers++] = array[i];
}
/* do your stuff here */
free(even_numbers);
return 0;
}
First, you can never return a statically declared array from a function (even though you don't explicitly try, your Even array is destroyed when EvenNumber returns) Why? The function stack frame for EvenNumber is released for reuse on return and any locally declared arrays are no longer valid.
You either need to pass a second array as a parameter to EvenNumber, or you can dynamically allocate storage for Even in EvenNumber (with, e.g. malloc or calloc or realloc) and return a pointer to the beginning of the array. (you must also have some way to return the size or use a constant for a max size).
There is no need to use % (modulo) to test whether a number is odd/even. All you need to do is look at bit-0 (little endian). If it is 0, then the number is odd, if it is 1, then its even. Much more efficient than calling modulo which incorporates division.
Finally, main is type int and therefore returns a value.
Putting those pieces together, you can do something simple like the following:
#include <stdio.h>
#include <stdlib.h>
void EvenNumber (int *array, int *even, int size, int *esize);
int main (void)
{
int array[] = { 10,2,9,3,1,98,8 },
i, n = sizeof array / sizeof *array,
even[n], /* a VLA of the same size as array is fine here */
esize = 0;
EvenNumber (array, even, n, &esize);
printf ("array: ");
for (i = 0; i < n; i++)
printf (" %2d", array[i]);
printf ("\neven : ");
for (i = 0; i < esize; i++)
printf (" %2d", even[i]);
putchar ('\n');
return 0;
}
void EvenNumber (int *array, int *even, int size, int *esize)
{
int i;
for (i = 0; i < size; i++)
if ((array[i] & 1) == 0) /* simply looking at bit-0 is all you need */
even[(*esize)++] = array[i];
}
Note: esize is passed as a pointer to EvenNumber and updated within the function so that the number of elements in even are available back in the calling function (main() here).
Example Use/Output
$ ./bin/arrayeven
array: 10 2 9 3 1 98 8
even : 10 2 98 8
Let me know if you have any further questions.

C: Dynamic memory allocation using pointer to array with fixed number of chars

so I guess this is more a stylistic question.
I need to write into a dynamic array of elements with the size of 3 bytes. (bitmap with pixel size of 24bpp)
So, every element would have to be a char[3].
If I want to avoid using a struct pixel{ char R, char G, char B}, to avoid the usage of preprocessor statements, is it possible to write it as
char* pixel[3]
and allocate in steps of 3*sizeof(char)?
To account for height and width, I would need a char** pixel[3], and having to allocate in single char steps would make that a char*** pixel.
So I guess I'm looking for a way to avoid using a pointer-pointer-pointer.
Thanks!
Do you mean N blocks of 3 unsigned char' s [0...255]?
Note the difference:
unsigned char *pixel[3] -> array of pointers to char
Vs
unsigned char (*pixel)[3] -> pointer to array of chars
#include <stdio.h>
#include <stdlib.h>
#define N 4
int main(void)
{
unsigned char (*pixel)[3];
pixel = malloc(sizeof(*pixel) * N);
pixel[0][0] = 0;
pixel[0][1] = 128;
pixel[0][2] = 255;
/* ... */
pixel[3][0] = 0;
pixel[3][1] = 128;
pixel[3][2] = 255;
printf("R:%d G:%d B:%d\n", pixel[0][0], pixel[0][1], pixel[0][2]);
free(pixel);
return 0;
}
If you don't know N before hand replace malloc with realloc
You can simulate this using a 1D array. Say you want to allocate a wxh rectangle of pixels. You could write.
char *pixels = (char *) malloc(w*h*3*sizeof(char));
Now the 3 color bytes appear contiguous in memory and you can access any cell using some arithmetic
You can get/set the color channels at cell (i,j) by defining the macros:
#define r(p, i, j) ((p)[(3*((w)*(i)+(j)))])
#define g(p, i, j) ((p)[(3*((w)*(i)+(j)) + 1)])
#define b(p, i, j) ((p)[(3*((w)*(i)+(j)) + 2)])
Call looks like r(pixels, 0, 1).
If you don't want structs, you can't avoid writing char***.
But you can use a type, to make it more stylish.
So the best solution matching your requirements seems to be:
#include <stdlib.h>
typedef char*** pixelmap_t;
int main() {
int channels = 3, width = 10, height = 10;
pixelmap_t test = malloc(width*height*channels);
int x = 1, y = 2, channel = 0;
test[x][y][channel] = 3;
free(test);
return 0;
}
It seems, I totally fucked up. I confused the following two things:
When you declare a static 3D-Array pixels[100][100][3], then the type is not char***. It is a one-dimensional array of 300 consecutive items in memory.
When you declare a char*** and assign 300 items in memory, then dereferencing all of the dimensions with the pixels[x][y][z] syntax results in derefrencing the first dimension and interpreting the value in memory as pointer and derefrencing this pointer instead of computing the correct offset in a 3D-Array.
That means, I overlooked, that the array[x][y][z] accessor syntax has two different semantics. The first I would call the array ([x][y][z]) semantic for 3D-arrays and the second I would call the ((array[x])[y])[z] semantics for char*** (I used the brackets for emphasizing).
This code snipped compiles and works (tested it) - but does not use heap memory.
For heap memory I don't know an other solution than those, which have been posted already (malloc(width*height*channels) and access with pixels[c + channels*(y + x*height)]).
#include <stdlib.h>
#include <stdio.h>
int main() {
int channels = 3, width = 10, height = 10;
char test[width][height][channels];
char *ptr = (char*) test;
for (int i = 0 ; i < channels * width * height ; i++) {
ptr[i] = (char) (i % 255);
}
for (int x = 0 ; x < width ; x++) {
for (int y = 0 ; y < height ; y++) {
for (int c = 0 ; c < channels ; c++) {
int d = (int) test[x][y][c];
printf("%d %d - %d : %d\n", x, y, c, d);
}
}
}
return 0;
}

Adding Zero padding to an array

I am doing a GHASH for the AES-GCM implementation.
and i need to implement this
where v is the bit length of the final block of A, u is the bit length of the final block of C, and || denotes concatenation of bit strings.
How can I do the concatenation of A block to fill in the zeros padding from v to 128 bit, as I do not know the length of the whole block of A.
So I just take the A block and XOR it with an array of 128 bits
void GHASH(uint8_t H[16], uint8_t len_A, uint8_t A_i[len_A], uint8_t len_C,
uint8_t C_i[len_C], uint8_t X_i[16]) {
uint8_t m;
uint8_t n;
uint8_t i;
uint8_t j;
uint8_t zeros[16] = {0};
if (i == m + n) {
for(j=16; j>=0; j--){
C_i[j] = C_i[j] ^ zeros[j]; //XOR with zero array to fill in 0 of length 128-u
tmp[j] = X_i[j] ^ C_i[j]; // X[m+n+1] XOR C[i] left shift by (128bit-u) and store into tmp
gmul(tmp, H, X_i); //Do Multiplication of tmp to H and store into X
}
}
I am pretty sure that I am not correct. But I have no idea how to do it.
It seems to me that you've got several issues here, and conflating them is a big part of the problem. It'll be much easier when you separate them.
First: passing in a parameter of the form uint8_t len_A, uint8_t A_i[len_A] is not proper syntax and won't give you what you want. You're actually getting uint8_t len_A, uint8_t * A_i, and the length of A_i is determined by how it was declared on the level above, not how you tried to pass it in. (Note that uint8_t * A and uint8_t A[] are functionally identical here; the difference is mostly syntactic sugar for the programmer.)
On the level above, since I don't know if it was declared by malloc() or on the stack, I'm not going to get fancy with memory management issues. I'm going to use local storage for my suggestion.
Unit clarity: You've got a bad case going on here: bit vs. byte vs. block length. Without knowing the core algorithm, it appears to me that the undeclared m & n are block lengths of A & C; i.e., A is m blocks long, and C is n blocks long, and in both cases the last block is not required to be full length. You're passing in len_A & len_C without telling us (or using them in code so we can see) whether they're the bit length u/v, the byte length of A_i/C_i, or the total length of A/C, in bits or bytes or blocks. Based on the (incorrect) declaration, I'm assuming they're the length of A_i/C_i in bytes, but it's not obvious... nor is it the obvious thing to pass. By the name, I would have guessed it to be the length of A/C in bits. Hint: if your units are in the names, it becomes obvious when you try to add bitLenA to byteLenB.
Iteration control: You appear to be passing in 16-byte blocks for the i'th iteration, but not passing in i. Either pass in i, or pass in the full A & C instead of A_i & C_i. You're also using m & n without setting them or passing them in; the same issue applied. I'll just pretend they're all correct at the moment of use and let you fix that.
Finally, I don't understand the summation notation for the i=m+n+1 case, in particular how len(A) & len(C) are treated, but you're not asking about that case so I'll ignore it.
Given all that, let's look at your function:
void GHASH(uint8_t H[], uint8_t len_A, uint8_t A_i[], uint8_t len_C, uint8_t C_i[], uint8_t X_i[]) {
uint8_t tmpAC[16] = {0};
uint8_t tmp[16];
uint8_t * pAC = tmpAC;
if (i == 0) { // Initialization case
for (j=0; j<len_A; ++j) {
X_i[j] = 0;
}
return;
} else if (i < m) { // Use the input memory for A
pAC = A_i;
} else if (i == m) { // Use temp memory init'ed to 0; copy in A as far as it goes
for (j=0; j<len_A; ++j) {
pAC[j] = A_i[j];
}
} else if (i < m+n) { // Use the input memory for C
pAC = C_i;
} else if (i == m+n) { // Use temp memory init'ed to 0; copy in C as far as it goes
for (j=0; j<len_A; ++j) {
pAC[j] = C_i[j];
}
} else if (i == m+n+1) { // Do something unclear to me. Maybe this?
// Use temp memory init'ed to 0; copy in len(A) & len(C)
pAC[0] = len_A; // in blocks? bits? bytes?
pAC[1] = len_C; // in blocks? bits? bytes?
}
for(j=16; j>=0; j--){
tmp[j] = X_i[j] ^ pAC[j]; // X[m+n+1] XOR A or C[i] and store into tmp
gmul(tmp, H, X_i); //Do Multiplication of tmp to H and store into X
}
}
We only copy memory in the last block of A or C, and use local memory for the copy. Most blocks are handled with a single pointer copy to point to the correct bit of input memory.
if you don't care about every little bit of efficiency (i assume this is to experiment, and not for real use?) just reallocate and pad (in practice, you could round up and calloc when you first declare these):
size_t round16(size_t n) {
// if n isn't a multiple of 16, round up to next multiple
if (n % 16) return 16 * (1 + n / 16);
return n;
}
size_t realloc16(uint8_t **data, size_t len) {
// if len isn't a multiple of 16, extend with 0s to next multiple
size_t n = round16(len);
*data = realloc(*data, n);
for (size_t i = len; i < n; ++i) (*data)[i] = 0;
return n;
}
void xor16(uint8_t *result, uint8_t *a, uint8_t *b) {
// 16 byte xor
for (size_t i = 0; i < 16; ++i) result[i] = a[i] ^ b[i];
}
void xorandmult(uint8_t *x, uint8_t *data, size_t n, unint8_t *h) {
// run along the length of the (extended) data, xoring and mutliplying
uint8_t tmp[16];
for (size_t i = 0; i < n / 16; ++i) {
xor16(tmp, x, data+i*16);
multgcm(x, h, tmp);
}
}
void ghash(uint8_t *x, uint8_t **a, size_t len_a, uint8_t **c, size_t len_c, uint8_t *h) {
size_t m = realloc16(a, len_a);
xorandmult(x, *a, m, h);
size_t n = realloc16(c, len_c);
xorandmult(x, *c, n, h);
// then handle lengths
}
uint8_t x[16] = {0};
ghash(x, &a, len_a, &c, len_c, h);
disclaimer - no expert, just skimmed the spec. code uncompiled, unchecked, and not intended for "real" use. also, the spec supports arbitrary (bit) lengths, but i assume you're working in bytes.
also, i am still not sure i am answering the right question.

Resources