1

Namaste! I want to initialize my struct array position 0 myList.items[0] with a pointer to my item struct, but it prints out jibberish on the relevant positions when I print it out from my print function. It changes what was previously initialized (for test) so I know it works partially, but what's causing the bad output and what should be changed?

Before:

----My Shopping list---------

1 - Chocolate 40 100g

2 - Fishsauce 9 l

After:

----My Shopping list---------

1 - c┴®¶²` 128565603 ■   lüIv

2 - Fishsauce 9 l

typedef struct{
        char name[20];
        int amount;
        char amountType[10];
}item;

typedef struct{
        item *items[5];
        int length;
}list;

int addItemToList(list *myList);

main(void)
{
    list myList;
    myList.length = 0;
    for(int i; i<5;i++)
    {
        myList.items[i] = NULL;
    }
    addItemToList(&myList);
    return 0;
}


int addItemToList(list *myList)
{
    item newItem = {"Potatoes",2, "kg"};
    myList->items[myList->length]=&newItem; //Something wrong here?
    myList->length++;
    printf ("Added [%s %i %s] as #%i.", newItem.name, newItem.amount,newItem.amountType, myList->length);
return 0;
}
2
  • Your attempting to place a stack allocated struct inside a heap (malloc ) allocated struct. This won't work. Commented May 15, 2018 at 20:25
  • That makes sense, made me refresh my memory so to say :) Commented May 15, 2018 at 21:00

3 Answers 3

1

This:

int addItemToList(list *myList)
{
    item newItem = {"Potatoes",2, "kg"};

That allocates newItem on the stack. That means the memory for it will go away when addItemToList is completed, so &newItem will be pointing to gibberish later. It will be fine while still running code in addItemToList, but then after that the memory contents will be replaced in any further functions that are called.

You can either use malloc to allocate some memory for newItem, or you can allocate newItem on the stack in your main function and pass the pointer to newItem to any other called functions.

Sign up to request clarification or add additional context in comments.

Comments

0

You cannot initialize a struct on the stack and then pass the pointer to that struct to a different struct that lives longer than that stack frame is open. Once the function returns, the stack frame where your item was allocated will close and the assigned values to the fields will be gone.

You need an initializer function with a heap allocated struct like this:

item* item_new(const char* name, int amount, const char* amountType);

Then your initialization function should:

  1. call Malloc for the size of struct,
  2. Copy the name and amountType strings to the struct.
  3. copy the amount to the struct.

Then you can do this: myList->items[myList->length]=newItem;, where newItem is created by your init function.

Comments

0

You are mixing stack and heap memory, I rewriten it for you, it should give you some sense what went wrong. Also always free allocated memory its no java:

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

typedef struct{
        char name[20];
        int amount;
        char amountType[10];
}item;

typedef struct{
        item *items[5];
        int length;
}list;

int addItemToList(list *myList);

int main(void)
{
    list myList;
    myList.length = 0;
    for(int i; i<5;i++)
    {
        myList.items[i] = 0;
    }

    addItemToList(&myList);

    for(int i; i<myList.length; i++)
    {
        free(myList.items[i]);
    }

    return 0;
}


int addItemToList(list *myList)
{
    item* newItem = malloc(sizeof(item));
    strcpy(newItem->name, "Potatoes");
    newItem->amount = 2;
    strcpy(newItem->amountType, "kg");
    myList->items[myList->length++] = newItem; //Something wrong here?
    printf ("Added [%s %i %s] as #%i.\n", newItem->name, newItem->amount, newItem->amountType, myList->length);
    return 0;
}

1 Comment

Wow, great! Thanks! And thanks for the advice on freeing the memory.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.