【发布时间】:2020-05-17 15:27:34
【问题描述】:
我正在开发一个 api 来为我的 stm32 项目 (stm32f0) 创建菜单结构。我创建了一个结构来表示菜单中的一个项目,并通过建立指向菜单中父结构和子结构的指针关系来跟踪上下导航。根据菜单项是设置/参数(目标)还是只是文件夹,有 2 种不同的类型、文件夹和目标。
这是我创建新文件夹项的功能。 parentItem 被传递给为新菜单项创建链接的函数,但是由于文件夹(父项)可能包含多个子项,我需要动态分配内存以在父项中保存新子项的指针。我很难理解正确的指针语法来实现这一点。 我收到错误“从类型'MenuItem * {aka struct MenuItems *}'分配给类型'struct MenuItems'时类型不兼容”
这是我的带有 typedefs 的 .h 文件:
typedef enum
{
Folder,
Target
} ItemType;
typedef struct MenuItems
{
struct MenuItems *parent; // pointer to parent level item (-1 level)
struct MenuItems *child; // pointer to child level items (+1 level) (FOLDER ONLY)
uint8_t numChildren; // number of child items held by this item (FOLDER ONLY)
ItemType type; // whether item is a folder or target
uint8_t index; // assigned index of this item
uint8_t visible; // flag to set whether the item is visible to the user
void (*func)(); // pointer to the function when target is chosen
char name[ITEM_NAME_LENGTH];// displayed string for the menu item
} MenuItem;
这是我在 .c 中创建新文件夹项的函数:
MenuItem *menu_addFolder(MenuItem *parentItem, char name[])
{
// newIndex is used to assign the index to the new item
// Due to 0 indexing, this is used verbatim
// e.g. if numChildren = 1, the index assigned will be 1 as there are now 2 items
// By assigning the index before incrementing newChildren, 0 indexing is handled
uint8_t newIndex = parentItem->numChildren;
parentItem->numChildren++;
// create item and allocate memory
MenuItem *newItem = malloc(sizeof(MenuItem));
newItem->child = malloc(sizeof(MenuItem));
newItem->parent = malloc(sizeof(MenuItem));
// check for memory allocation errors
if(newItem == NULL || newItem->child == NULL || newItem->parent == NULL)
{
return NULL;
}
newItem->numChildren = 0;
newItem->type = Folder;
newItem->index = newIndex;
newItem->func = NULL;
strncpy(newItem->name, name, ITEM_NAME_LENGTH);
// establish the child-parent links
newItem->parent = parentItem;
// When a new folder is created, memory for a single child is allocated
// So for the first child assignment per parent, no new memory allocation is required
// However, for consecutive child assignments, new memory allocation is required
// If this is the first child assigned to the parent item
if(parentItem->numChildren == 1)
{
parentItem->child = newItem;
}
// If there are existing items assigned to the parent item
else if(parentItem->numChildren > 1)
{
parentItem->child = realloc(parentItem->child, sizeof(MenuItem) * parentItem->numChildren);
if(parentItem->child == NULL)
{
return NULL;
}
parentItem->child[newIndex] = newItem;
}
return newItem;
}
提前致谢!
【问题讨论】:
-
您应该始终指出哪一行代码会导致编译器错误。
-
代码执行
newItem->parent = malloc(sizeof(MenuItem));,然后在几行之后:newItem->parent = parentItem;,丢弃之前的分配。当然不需要第一次分配。 -
虽然可以指出函数中的明显问题,但如果没有A Minimal, Complete, and Verifiable Example (MCVE),就无法判断这是否是您所看到问题的根源。使用 MCVE 可以编译和验证代码的工作原理。
-
请注意,
void (*func)();没有指定函数所需的参数列表——参数列表可以是任何固定的参数列表(不是像printf()这样的变量参数;这需要一个适当的原型省略号, ...在签名的末尾。最好避免使用此类指向函数的非原型指针,尽管有时这样做可能会令人担忧。(这与您当前面临的问题完全相干;它可能变得相关不过稍后。) -
@samspencer 在 uC 设计中使用
malloc是一个坏习惯,应该避免。许多嵌入式编码标准明确禁止动态分配。 Yuor 代码表明您刚刚开始使用 uC,并且已经习惯了使用几乎无限资源的大型机器。
标签: c arrays pointers struct dynamic