This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Is it possible for HEAP to have a bad byte or bytes?

Other Parts Discussed in Thread: CC2530, Z-STACK

Hi,

I have a strange problem. I have a function that copies data from a received message to the heap using osal_mem_alloc. The first time through I always get a rogue value in the same place amongst good data when using osal_mem_alloc. Subsequent function calls work perfectly. 

If I drop osal_mem_alloc and declare a simple array then it works perfectly from the start.

Here is what I'm doing:

//assign some heap space to pointer
historical_data_buffer_ptr = ((HISTORICAL_DATA_BUFFER *)osal_mem_alloc(length_of_data));   //*** this line changes the data in the incoming message- why?

//check that some heap space was assigned
if(historical_data_buffer_ptr != NULL)
{
    //copy the data from the incoming message to the heap.
    osal_memcpy(&historical_data_buffer_ptr->historical_buffer, &function_msg_in->incoming_msg.cmd.Data[HDR_DATA_LOCATION], length_of_data);
}

The only thing I can think of is that as the incoming message is also in the heap and not deallocated until after this function call. My heap allocation must be changing one byte of the incoming message, but how?

I'd like to use the dynamic heap but as it stands, I am forced to used a static array instead.

I am using z-stack home 1.2.1 on CC2530.

Any ideas any one?

Andy

  • I don't think so. Why is your actual problem?
  • Andy,

    You can trust that OSAL manages memory correctly. 'Weird' changes in HEAP are caused by buffer overruns.


    In your code I see that you allocate space for a HISTORICAL_DATA_BUFFER which seems to be a struct with a member historical_buffer.

    The memcpy starts writing data at the address of this member, not of the struct.

    You should allocate memory for the whole struct, i.e. sizeof(HISTORICAL_DATA_BUFFER) + length_of_data.

    BR,

    Sjef.

  • Hi BR,

    Thank you for your reply. It works!

    But what's going on? I know this is off topic as it's more C programming/compiler based....

    My assumptions:

    1) I haven't looked too closely at how my struct is being stored in memory. I assumed that the address of a the struct is the same as the address of the member of the struct as there is only one member.

    2) I don't have to osal_mem_alloc the size of the whole buffer/struct as the data being copied is checked to be =< than MAX_LOAD_HISTORICAL_DATA_BUFFER_SIZE. I can aloc just length_of_data.

    typedef struct __tag_historical_data_buffer
    {
    uint8 historical_buffer[MAX_LOAD_HISTORICAL_DATA_BUFFER_SIZE];
    
    } HISTORICAL_DATA_BUFFER;



    Obviously I'm wrong in my assumptions as your suggestion works, but in the interest to keep the heap usage down to a minimum, I thought it prudent to only alloc the size of data I need each time, and not have to alloc the maximum size, say 64 bytes, when my data may only be 2 bytes.

    Thanks for your help,

    Andy

  • I was thinking you had something more along the lines of:

    typedef struct {

     uint8 size;

     uint8 data[];

     } dataBuffer_t;

    A variable length array as a member of a struct (naturally, because you

    would want to store its length with it) is declared like this. Note that

    it can only be the last member of the struct.

    Then you could do:

    dataBuffer_t *buf;

    buf = osal_mem_alloc(sizeof(dataBuffer_t) + data_len);

    buf->size = data_len;

    osal_memcpy(buf->data, src, data_len);