在C中设置结构中的字节数组指针

在C中设置结构中的字节数组指针,c,struct,malloc,bytearray,C,Struct,Malloc,Bytearray,我有一个包含指向字节数组指针的结构 为了设置指针,我尝试了以下两种方法: 1使用malloc然后使用memcpy字节数组数据(在下面的代码中注释掉) 2简单地复制指针 #include "stdlib.h" #include "string.h" #include "stdio.h" typedef struct _element { unsigned char *pValue; int nLength; } Element; Element* ElementCreate(v

我有一个包含指向字节数组指针的结构

为了设置指针,我尝试了以下两种方法:

1使用malloc然后使用memcpy字节数组数据(在下面的代码中注释掉)

2简单地复制指针

#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;
}

会写出垃圾数据,但似乎效果不错。为什么?

这是一种未定义的行为,其中一个子集是“正常工作”

数组
myValue
在下一次
}
时超出范围。此时,存储
myValue
的内存位置可以恢复,但可能不会保持不变,因此代码似乎可以工作

正确的方法是当我们进入

{
    unsigned char myValue[] = { 0x01, 0x02, 0x03 };
    int nLength = sizeof(myValue) / sizeof(myValue[0]);

    ElementSetValue(pElement, myValue, nLength);
}
这意味着将为myValue保留一个内存。当我们离开它时(在
}
之后),这意味着与myValue相关的内存不再保留,它是空闲的,但内容没有改变。这就是为什么你可以访问内存,而它的内容不会改变。 如果您的应用程序是多线程应用程序,那么与myValue meory相关的数据被另一个线程更改的风险很大,在这种情况下,您始终可以访问相同的内存空间,但您会发现内存内容发生了更改

{
    unsigned char myValue[] = { 0x01, 0x02, 0x03 };
    int nLength = sizeof(myValue) / sizeof(myValue[0]);

    ElementSetValue(pElement, myValue, nLength);
}