0

I've read all other questions but response aren't helping me so much. Once again, I'm not a developer but a wood worker trying to make something far too complicated for his own brain.

I work on a PIC its alignment is 4 bytes, all structures are define with attribute((packed)).

I've found a way to do it but it uses malloc and str/mem-cpy, methods that aren't safe for interrupt, or for malloc that I shouldn't be using at all (cf. my previous question)

Said structure contains 16 unsigned char, one s16 (2 bytes) et three s32 (4 bytes), so its 30 bytes long, with 4bytes alignement making it 32bytes long. (char are coded on 8bits).

1) Am I wrong until here?

int len =sizeof(data_out.point[i]);
    unsigned char* raw;
    raw = malloc(len);
    memcpy(raw, &data_out.point[i], len);
    Data_res[count].pData =  malloc(len);
    for (int k = 0; k<len; k++)
    {
        Data_res[count].pData[k] = (uint8_t)(raw[k]);
    }
    Data_res[count].DataLen=len;
    count++; 
}

data_out is a stucture (members are not relevant except following one) point is the structure described before.

Data_res is a structure that store an uchar buffer (pData) and contains lenght and status (locked, writing, etc to avoid multi-access).

1) its not working 100%, sometimes result are really strange.

2) since yesterday I understand why its bad (malloc on not shared memory, casting malloc, interruption safety, etc).

How to do the same thing without mallocs/memcpy ?

note: I need this for debug output, I was going to just let it go, but I don't like to keep things unfinished...

A.albin
  • 274
  • 2
  • 15

1 Answers1

1
  1. Don't cast the result of malloc in C. If you have to cast, you're using a C++ compiler, and you should be using new instead of malloc.
  2. sizeof is an operator (not a function) that determines the size of objects of that type (as a size_t, not an int), so if data.point[i] is a char * for example, sizeof data.point[i] is the same value as sizeof (char *). It is a common mistake to assume sizeof determines the size of the object pointed at by a pointer; that hold true for array types, but not pointer types.
  3. You're leaking memory pointed at by raw when your function returns. You should be using automatic storage duration rather than dynamic allocation there. i.e. unsigned char raw[len];.
  4. You should be performing machine-independent serialisation, e.g. translating each field to a value that doesn't depend upon machine architecture, if you're planning on transporting this data to other machines.
  5. Finally, to answer your question, the only way you can substitute Data_res[count].pData = malloc(len); seems that you need some other object (see automatic storage duration above) to point to instead, i.e. Data_res[count].pData = raw;... You might need to declare raw in the caller function, to avoid it being destroyed when the function you provided returns.
Community
  • 1
  • 1
autistic
  • 1
  • 3
  • 35
  • 80
  • 1) I Know it since yesterday, I just provided the code I was using. 2) data.point[i] is a structure 3) raw is passed to free, I missed it when I pasted the code, will fix post, thanks for pointing it out 4) its passing to the a different hardware running the on the same pic with same software (redundancy) 5) I will try to init Data_res[count].pData at startup then, thank you – A.albin Apr 07 '17 at 08:12
  • I deleted this method to just recast the structure into a pointer where it was called. it might not be elegant but it works – A.albin Apr 20 '17 at 04:15