如果我们在SomeFunction内定义一个数组,它在其作用域中是有效的。但它到底存放在哪里呢?局部变量通常存储在堆栈上,但我问自己是否整个数组都存储在堆栈上,或者仅仅是指向数据字段的指针,数据实际上存储在那里(比如调用malloc在堆上分配内存)。浅谈单片机的实现。
所以这个问题也引出了另一个问题。如果数据存储在堆中,如果指针将被保存到pdata并在不同的作用域(SomeOtherFunction)中访问,则该操作是否有效?数据是否可以在那里使用,或者我如何知道数据是否不再有效?

#define DATAFIELDLEN 127

static uint8_t* pdata;

static void SomeFunction()
{
    uint8_t dataField[DATAFIELDLEN] = {};

    // Write some stuff to the datafield

    pdata = dataField;  // Save pointer to the datafield
}

static void SomeOtherFunction()
{
    // Use datafield here
    for(uint8_t ii=0; ii<DATAFIELDLEN; ii++){
        // Dereference Data here
        someOperation(pdata[ii]);       // <-------- is the data valid here?
    }
}

void main()
{
    SomeFunction();
    SomeOtherFunction();
}

另一种可能是将该文件全局范围内的datafield定义为static。然后将数据存储在初始化为零的数据中,并在整个文件中有效。但是在我提出的方法中,我想通过不让这个数据字段一直可用来节省一些内存空间。或者还有其他有用的做法吗?

最佳答案

不,那里的数据无效。你可以让它有效,但它真的很危险。让我解释一下。
当您在SomeFunction()中分配数组时,它是在堆栈上分配的。这意味着,一旦您从该函数返回,内存将在将来某个时候随着堆栈的使用而被覆盖。将指针解引用到实际上无法控制的内存区域。有时你可能会逃脱惩罚,但这绝对是一种未定义的行为。
另一方面,虽然实际上并不建议,但您可以将该数组标记为static。如果您这样做了,它将不再在堆栈上分配,当它超出范围时,您可以继续访问它。请明确,我不推荐这是一个好的解决方案。
使这个保持有效的正确方法是malloc()它的内存并用pdata指向它。

关于c - 本地定义的数组在其定义的功能之外是否有效?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35483484/

10-11 23:18
查看更多