我们说我有一个结构和以下功能:
头文件中的结构:
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]与我在函数外部取消引用它时得到的数据不同。有什么想法吗?
答案 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这样的程序是多么优雅和惯用。