Jam Jam - 2 months ago 7
C Question

How to store results by advancing memory address in c

Example 1:

#include <stdio.h>
#include <string.h>
void saveData(void* data) // only allow to use void* data
{
// ...After some calculation:
int inputData[5] = {1,2,3,4,5};

memcpy((int*)data, inputData, sizeof(inputData));
}
int main()
{
int myNum[256];

saveData((void*)myNum);

printf("\n%d%d%d%d%d\n",myNum[0],myNum[1],myNum[2],myNum[3],myNum[4]);

}


I have an int array in main, and pass the array into function saveData,

In function savaData, I save the inputData[5] into myNum[256];

It works fine.

Example 2:

What if I have a struct array instead of int array:

#include <stdio.h>
#include <string.h>
struct Analysis{
int a;
int b[10];
};

void saveData(void* data, size_t size) // update here for size param
{
struct Analysis a1;
a1.a = 1;
memset(a1.b, 0, 10*sizeof(int));

for(int i=0; i<10; i++)
{
a1.b[i] = 1;
printf("%d", a1.b[i]);
}

struct Analysis a2;
a2.a = 2;
memset(a2.b, 0, 10*sizeof(int));

for(int i=0; i<10; i++)
{
a2.b[i] = 2;
printf("%d", a2.b[i]);
}

//memcpy((int*)data, inputData, sizeof(inputData));
//How can I copy a1 and a2 into memory space of data(ana[2]) here;
}
int main()
{
struct Analysis ana[2];

saveData((void*)ana, sizeof ana[0]); // update here

for(int i=0; i<2; i++)
{
printf("\n%d\n", ana[i].a);
for(int j=0; j<10; j++)
printf("%d", ana[i].b[j]);
}
}


So, How can I copy a1 and a2 into memory of ana[2] in function saveData?

What I think is:

I can cast data(ana) into char* to go through its address and store results;

Once I finish ana[0], I can use sizeof(ana[0]) to advance the pointer to next

one(ana[1]).

****UPDATE:--------------------------------------------------------------------

size - This is the size of the struct used to hold the results for each file. It is VITAL to pass this information. Without this size, you will not be able to correctly access the slots of the array that you have passed to map. Since results is a void pointer, in order to support multiple types of arrays, the regular pointer arithmetic will not work correctly, hence size is crucial here.

Answer

So, How can I copy a1 and a2 into memory of ana[2] in function saveData?

There are many ways. One is the exact analog of the way you demonstrate doing it with ints:

void saveData(void* data)
{
  // ...After some calculation: 
  struct Analysis aa[2] = {
    { 1, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } },
    { 2, { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 } }
  };

  // note: no need to cast 'data' or 'aa' as long as a prototype is visible
  memcpy(data, aa, sizeof(aa));
}

Of course, all this begs the question of why you are declaring saveData()'s parameter as type void * when your code makes key assumptions about the type of the its referent and the capacity (and existence) of the containing array. It feels like you are being overly generic.

What I think is:

I can cast data(ana) into char* to go through its address and store results;

Once I finish ana[0], I can use sizeof(ana[0]) to advance the pointer to next one(ana[1]).

Yes, you can do that, but why? If you're going to convert the pointer's type, then convert it to the type of the data you are writing to it (e.g. struct Analysis *) and use it just like an array. (And note, too, that the assignment operator works on structs and unions.):

void saveData(void* data)
{
  // ...After some calculation: 
  struct Analysis aa[2] = {
    { 1, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } },
    { 2, { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 } }
  };

  struct Analysis *data_array = data;

  for (int i = 0; i < 2; i++) {
      data_array[i] = aa[i];
  }    
}

That's pretty much equivalent to what you describe, but cleaner and clearer.

Comments