I have a structure that contains a pointer to a byte array.
To set the pointer I’ve tried the following two ways:
1 Use malloc then memcpy byte array data (commented out in code below).
2 Simply copy pointer.
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
typedef struct _element
{
unsigned char *pValue;
int nLength;
} Element;
Element* ElementCreate(void)
{
Element *pElement = (Element*)malloc(sizeof(*pElement));
pElement->pValue = NULL;
pElement->nLength = 0;
return pElement;
}
void ElementDestroy(Element **ppElement)
{
Element *pElement = NULL;
if (!ppElement)
return;
pElement = *ppElement;
//free(pElement->pValue);
//pElement->pValue = NULL;
free(pElement);
*ppElement = NULL;
}
void ElementSetValue(Element *pElement, unsigned char *pValue, int nLength)
{
//pElement->pValue = (unsigned char*)malloc(nLength * sizeof(*(pElement->pValue)));
//if (!(pElement->pValue))
// return;
//memcpy(pElement->pValue, pValue, nLength);
pElement->pValue = pValue;
pElement->nLength = nLength;
}
void ElementWriteValue(const Element *pElement)
{
int nIndex = 0;
for (; nIndex < pElement->nLength; nIndex++)
printf("%02X ", pElement->pValue[nIndex]);
}
int main(void)
{
//unsigned char myValue[] = { 0x01, 0x02, 0x03 };
//int nLength = sizeof(myValue) / sizeof(myValue[0]);
Element *pElement = ElementCreate();
{
unsigned char myValue[] = { 0x01, 0x02, 0x03 };
int nLength = sizeof(myValue) / sizeof(myValue[0]);
ElementSetValue(pElement, myValue, nLength);
}
// How come this writes out correct value?
ElementWriteValue(pElement);
ElementDestroy(&pElement);
return 0;
}
(Error checks are omitted for brevity)
Which way is correct?
I’d expect 2 to fail because myValue will be destroyed after the “}” so
printf("%02X ", pElement->pValue[nIndex]);
would write out rubbish data but it seems to work OK. Why?
It is undefined behaviour, of which a subset is to “work correctly”.
The array
myValueis out of scope at the next}. At this point the memory location in whichmyValuewas stored is available to be resused, but it may not be leaving it unchanged and hence the code appears to work.The correct approach is to
malloc(),memcpy()andfree().