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

时间:2012-09-26 10:55:35

标签: 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(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;
}

(为简洁起见,省略了错误检查)

哪种方式正确?

我希望2失败,因为myValue会在“}”之后销毁,所以

printf("%02X ", pElement->pValue[nIndex]);

会写出垃圾数据,但似乎工作正常。为什么呢?

2 个答案:

答案 0 :(得分:1)

这是未定义的行为,其子集是“正常工作”。

数组myValue超出了下一个}的范围。此时,存储myValue的内存位置可以重新使用,但它可能不会保持不变,因此代码似乎可以正常工作。

正确的方法是malloc()memcpy()free()

答案 1 :(得分:0)

当我们进入

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

    ElementSetValue(pElement, myValue, nLength);
}

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