-1

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

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

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]);

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

4

2 回答 2

1

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

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

正确的做法是malloc(),memcpy()free()

于 2012-09-26T11:07:10.757 回答
0

当我们进入

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

    ElementSetValue(pElement, myValue, nLength);
}

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

于 2012-09-26T11:11:40.890 回答