I'm working on an api to create menu structures for my stm32 project (stm32f0). I've created a struct that represents an item in the menu, and navigation up and down levels is tracked by establishing a relationship of pointers to parent and child structs in the menu. There are 2 different types, folders, and targets depending on whether a menu item is a setting/parameter (target), or just a folder.
Here is my function to create a new folder item. The parentItem is passed to the function which inheretly creates the link for the new menu item, however because a folder (parent) may contain multiple child items, I need to dynamically allocate memory to hold the pointer for the new child in the parent. I'm having difficulty understanding the correct pointer syntax to achieve this as. I'm getting the error "incompatible types when assigning to type 'struct MenuItems' from type 'MenuItem * {aka struct MenuItems *}'"
Here is my .h file with the typedefs:
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;
And this is my function in the .c to create a new folder item:
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;
}
Thanks in advance!
newItem->parent = malloc(sizeof(MenuItem));and then a few lines later:newItem->parent = parentItem;, throwing away the previous allocation. Certainly the first assignment was not needed.void (*func)();doesn't specify the argument list required by the function — the argument list can be any fixed list of arguments (not variable arguments likeprintf(); that requires a proper prototype with ellipsis, ...at the end of the signature. It is best to avoid such non-prototype pointers to functions, though it can sometimes be fraught to do so. (This is wholly tangential to the problem you currently face; it may become relevant later, though.)mallocin the uC design is a bad habit and should be avoided. Many embedded coding standards explicit ban the dynamic allocation. Yuor code shows that you just started with the uCs and have habits form the big machines with almost infinitive resources.