取消引用结构中的数组(在C中)

时间:2016-06-14 22:03:23

标签: c arrays struct

我们说我有一个结构和以下功能:

头文件中的

结构:

typedef struct {
uint8_t length;
uint8_t data[8];
} simple_vector;

功能:

simple_vector* SD_cmd(uint8_t cmd, uint32_t arg, uint8_t crc, uint8_t read_cnt){

simple_vector vector;

//stuff happens and the simple_vector is manipulated

return &vector;
}

如何使用 - >访问数组的非零元素?操作

让我们假设一个函数返回一个指向这个结构的指针:

simple_vector *response;
response = SD_cmd(8, 0x000001AA, 0x87, 5);
uint8_t value = response->data[3];

上述代码段中的最后一行未返回正确的值。我已经调试了(在一个mcu上)并验证了函数中的数据[3]与我在函数外部取消引用它时得到的数据不同。有什么想法吗?

2 个答案:

答案 0 :(得分:0)

您将返回本地变量的地址。当控件离开包含变量定义的块(在本例中为您的函数)时,变量将被销毁,并且您将留下无效指针。

您的代码有未定义的行为。

您还应该检查您的编译器是否有针对此案例的警告选项。例如。 gcc有-Wreturn-local-addr(我认为默认情况下已启用),它会警告您这种情况。

要解决此问题,您可以让函数获取指向结构的指针以将结果写入。这将使调用者有责任管理与结构相关联的内存。

你也可以按值返回一个struct,它会将它复制到调用者(在幕后这可能会编译成类似解决方案#1的函数;返回结构的函数通常是通过使它们采用隐藏的指针参数来实现的)。

或者你可以malloc动态结构。然后你必须检查错误(从NULL返回malloc)并且它成为调用者对free返回指针的责任。

最后,您可以使函数不返回任何内容(void),而是使用全局变量将值传递回调用者。通常不推荐这样做,因为全局变量会导致一些难以理解的程序逻辑(并且很难发现错误)。

答案 1 :(得分:0)

  

如何使用 - >访问数组的非零元素?操作

您可以通过首先访问变量来实现。假设8个元素的数组中的“非零”和“第十”元素是拼写错误,您可以轻松地创建和管理指向有效内存的指针,该指针也可以从调用函数访问 。一个显而易见的可能性是动态。这是一个快速演示修复程序,基于您的代码:

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>

typedef struct {
    uint8_t length;
    uint8_t data[8];
} simple_vector;

simple_vector* SD_cmd(uint8_t cmd, uint32_t arg, uint8_t crc, uint8_t read_cnt)
{
    simple_vector *vector = malloc(sizeof(simple_vector)); // pointer to malloc'd memory
    //stuff happens and the simple_vector is manipulated
    vector->data[3] = 42;
    return vector; //return the pointer
}

int main()
{
    if((simple_vector *response = SD_cmd(8, 0x000001AA, 0x87, 5)) == NULL){
        printf("Memory allocation error\n");
        return(1);
    }
    uint8_t value = response->data[3]; //the "last" line in question
    printf("%hhu\n", value);
    free(response);       //free the memory once you don't need it !
    return 0;
}
  

上述代码段中的最后一行未返回正确的值

> ./test
  42

请注意C这样的程序是多么优雅和惯用。