Copy 2D array to new buffer with memcpy - c

I want to copy an 2D array to a new 2D array within an internal buffer.
Let's suppose I have the following function:
uint8 the_2D_array[100][7];
void Get_2D_Array(uint8 **array)
{
*array = &the_2D_array[0][0]; // Function which returns pointer to the first element of the 2D array
}
Later in my code I'm expecting to do something like this:
myBuffered_Aray[100][7];
uint8 *pValues;
Get_2D_Array(&pValues)
{
for (uint8 i = 0; i < 100; i++)
{
for (uint8 j = 0; j < 7; j++)
{
(void)memcpy(myBuffered_Aray[i][j], (u8_t*)&pValues[i][j], sizeof(uint8));
}
}
}
The part with
(u8_t*)&pValues[i][j]
will not work because of "Expression must have pointer to object type".
How to do it correctly?

Related

Why the for loop is filling the whole array with the latest string?

Apologies if this is simple, but I am new to C. I am trying to create a loop that fills in an empty array of strings with multiple strings. However, at the end, the whole array is being filled with the latest element ! Below is the code:
int main(void)
{
string array_test[2];
char string_test[300];
for (int i = 0; i < 2; i++)
{
snprintf(string_test, sizeof(string_test),"Test: %i", i);
array_test[i] = string_test;
}
for (int i = 0; i < 2; i++)
{
printf("%s\n", array_test[i]);
}
}
This returns:
Test: 1
Test: 1
But I am expecting:
Test: 0
Test: 1
Because you are using the same buffer to save strings in all iterations. This will make previous strings overwritten by new strings.
Allocate separate buffers for each strings to avoid this.
/* put #include of required headers here */
int main(void)
{
string array_test[2];
char string_test[2][300];
for (int i = 0; i < 2; i++)
{
snprintf(string_test[i], sizeof(string_test[i]),"Test: %i", i);
array_test[i] = string_test[i];
}
for (int i = 0; i < 2; i++)
{
printf("%s\n", array_test[i]);
}
}
Why the for loop is filling the whole array with the latest string?
The for loop is filling the whole array of pointers array_test with the address of the first character of the character array string_test.
That is you declared an array of two pointers
string array_test[2];
and each element of the array points to the first character of the same array string_test
array_test[i] = string_test;
The statement above is equivalent to the following statement
array_test[i] = &string_test[0];
That is an array designator used in expressions with rare exceptions is converted to a pointer to its first element.
So you are outputting the same character array string_test using two pointers.
printf("%s\n", array_test[i]);
Instead of the array of pointers you could declare a two-dimensional character array like
char array_test[2][300];
and in the first for loop you could copy strings formed in the array string_test into elements of the array array_test like
strcpy( array_test[i], string_test );
In this case each element of the two-dimensional array will store its own string.
All elements in the string array point to the same buffer, so they all appear to have the same string, more precisely the value last composed into this buffer.
Using the typedef string for char * creates confusion about this fact, which is one more reason to not hide pointers behind typedefs.
You can allocate a copy of the string in the loop:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *array_test[2];
char string_test[300];
for (int i = 0; i < 2; i++) {
snprintf(string_test, sizeof(string_test), "Test: %i", i);
array_test[i] = strdup(string_test);
}
for (int i = 0; i < 2; i++) {
printf("%s\n", array_test[i]);
}
for (int i = 0; i < 2; i++) {
free(array_test[i]);
}
return 0;
}

Allocate and assign to memory efficiently

I would like to create a new array of values, and I am not sure how to do this efficiently. Since to create the new array I have to call a function, passing the old array as a parameter. Right now my code looks something like:
float *newMeasurements1;
newMeasurements1 = malloc(sizeof(calcNewArray(oldArray)));
newMeasurements1 = calcNewArray(oldArray);
float *calcNewArray(float *oldArray) {
float *newArray;
int new_size = sizeof(oldArray) - outliers;
newArray = malloc((new_size) * sizeof(float));
for (i = 0; i < new_size; i++) {
newArray[i] = oldArray[i];
}
return newArray;
}
I am not sure if this is the correct way to do this because I have to call the function once to know the size of the new array. And then call the function a second time to actually assign the array to the allocated memory.
How best can I do this?
This line is useless:
newMeasurements1 = malloc(sizeof(calcNewArray(oldArray)));
just write this:
newMeasurements1 = calcNewArray(oldArray);
The malloc is already done in calcNewArray.
But there is another problem in calcNewArray, arrays decay to pointers to their first element when you pass them to a function, therefore sizeof(oldArray) is no the sizte bof the array you passed to calcNewArray but it is the size of a pointer. You need to pass the size of oldArray explicitely as a second parameter:
float *calcNewArray(float *oldArray, int oldsize) {
float *newArray;
int new_size = oldsize - outliers;
newArray = malloc((new_size) * sizeof(float));
for (i = 0; i < new_size; i++) {
newArray[i] = oldArray[i];
}
return newArray;
}

function to modify 2d array to add row an a column using realloc

Whats wrong with this function, which is expected to add a row and a column to given 2D array? Matrix is symmetric.
void updateMatrix(double ***mat, int size, double *vec)
{ // mat is sizeXsize matrix, length of vec is size+1
*mat = (double**)realloc(*mat, (size + 1)*sizeof(double*));
(*mat)[size] = (double*)malloc((size + 1)*sizeof(double));
for(int i = 0; i < size + 1; i++) {
(*mat)[size][i] = vec[i];
}
for(int i = 0; i < size; i++) {
(*mat)[i] = (double*)realloc((*mat)[i], (size + 1)*sizeof(double));
(*mat)[i][size] = vec[i];
}
}
Your realloc is returning NULL in the second for loop..
I'm trying to figure out why.
Have you allocated everything before hand? Because chances are you might be passing a non NULL and non malloced pointer to realloc. And that is forbidden/will cause errors
Or, as says #MichaelDorgan , you could just be passing a gigantic size to your function but i sincereley hope you are not trying to allocate a few Go for an array. Otherwise i'm curious as to its use.

Struct array is printing garbage

I'm having an issue with printing out my struct array. It is initialized like so:
struct matrix tokens[nbrState][12];
I then try to print it out with this code:
printf("%d", tokens[0][0].state);
for(int q = 0; q < nbrState; q++){
for(int r = 0; r < 12; r++){
printf("%d", tokens[q][r].state);
}
}
How ever it just gives back
160833216083325909500442637211181530452359314445659095247095039827295039732859091035295039760059091066417471141950397584105931452485931525045870278695909110245869685280135590599950397784950397744593145248159314402459314316859095284905931452481590950044135934508013593144456590952470095039760058696836095039787258698266456147669503978565869965120593144552593143168419536358702168841950960596593143168950398056950398016593144552159315536059315450459095284905931445521015931545041048576587404166341899271605931553609503978729503978563593450804195363-1141298268758698266459314316800419611295039881600950398592587297673016950398176950397984091005908849605884315520000050-100950398592419
And I'm not sure why. I'm also filling the array with values using this for loop.
while ( fscanf ( fp, "%d/%d%c", &index, &separateInt, &separateChar) == 3) {
for(int i = 0; i < 12; i++){
tokens[index][i].state = separateInt;
}
}
You said
It is initialized like so
struct matrix tokens[nbrState][12];
But the above declaration does not initialize anything (unless your array is declared with static storage duration). A local array declared in this fashion will contain garbage at the beginning. That's apparently what you are printing.
If you want your array initialized, you have to initialize it yourself. For example, this declaration
struct matrix tokens[nbrState][12] = { 0 };
will initialize everything with zeros, assuming nbrState is a constant.
If nbrState is not a constant, then you will not be able to use a = { ... } initializer in the declaration. You will have to assign the initial values to your array elements manually, using a cycle or in some other way.

C-Passing an 3d array,allocation and population

let's say I have a functions below.
void function createBands(boolean option) {
int i, j;
int ***bands = (int ***)malloc((SIZE + 1) * sizeof(int **));
for (i = 0; i < SIZE; i++) {
bands[i] = (int **)malloc(HEIGHT * sizeof(int *));
for (j = 0; j < HEIGHT; j++)
bands[i][j] = (int *)malloc(WIDTH * sizeof(int));
}
iterator *it =
createIterator(params); // do not be confused it is a structure with
// methods andaeribute just like Iterator class in
// java . Methods are poniters to functions.
repare_array(bands[Size], it);
}
void prepare_array(int **band, iterator *it) { read_array(band, it); }
read_array(int **band, iterator *it) {
for (int i = 0; i < Height; i++)
band[i] = (int *)it->next();
}
// Now in Iterator.c I have the iterator structure with the methods etc I will
// write just some line form iterator.
void *next() {
byte *b =
a function that reads bytes form a file and returns byte * CORECTLY !!!;
return b == NULL ? NULL : bytetoT(b);
// this function make void form byte conversion but it doesnt work so I make
// only a cast in read_aray as you see. SUppose just return b wich is byte(i
// know in C isn't any byte but I redeclared all the types to be JAVA.)
}
the questions is where I should allocate the bands because in this situation the 1D vector return by function is ok because I see the values in the function scope. But when it is return to array[i] I got a unallocated 3dVector.
I need to recieve bands[size][i][j] with the data form b. In b the data is good then I ve gote bands null.
What I have do so far I make another allocation in prepare aray before the call to read_array where I allocate **band and then I have some results but I am not confident.
Sorry for the confusion! And every comment is good for me. Maybe what I have do is ok I do not know!.
I am not new to C I just do not work with pointers for a long time.
If it is a 2D pointer(**) you have to assign it with the address of 2D array and if it is 1D array you have to assign it with the address of 1D array.
For your read_array function
read_array(int**array...)
{
for(i=0;i<HEIGHT(the same as in allocation);i++)
`enter code here`array[i] = function();//function return an 1D array
}
Make sure that function() returns the address of the 1D array.

Resources