malloc() gives all structs I make the same address!!?

Discussion in 'Mac Programming' started by Dale Cooper, Sep 17, 2009.

  1. Dale Cooper macrumors regular

    Dale Cooper

    Joined:
    Sep 20, 2005
    #1
    Hi, I'm trying to get started with C. I've done a bit of java programming, so starting with memory allocation and all that stuff is posing some problems. Can anyone give me some advice as to why this code:



    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int i = 0;
    char nm = 'a';
    
    struct Item {
        char navn;
        int alder;
        struct Item *next;
    };
    
    void makeList(int k) {
        int j;
        struct Item *newPtr;
        for (j = 0; j < k; j++) {
            newPtr = malloc(sizeof(struct Item));
            struct Item new = *newPtr;
            printf("No %d has address %p\n", j, &new);
        }
    }
    
    int main(int argc, char** argv) {
        makeList(3);
        return (EXIT_SUCCESS);
    }
    gives this output:

    No 0 has address 0x7fff5fbffa50
    No 1 has address 0x7fff5fbffa50
    No 2 has address 0x7fff5fbffa50



    I want three structs with DIFFERENT addresses. My plan is to put these structs in a linked list, but its difficult when they just overwrite each other...
     
  2. kpua macrumors 6502

    Joined:
    Jul 25, 2006
    #2
    'struct Item new' is on the stack. A de-referenced pointer can't remember its original address. What you're doing here is, in effect, copying the contents of the malloc'd struct to one on the stack and then printing the stack address.

    'newPtr' is the address of the malloc'd struct. You most likely meant to print that out instead.
     
  3. Dale Cooper thread starter macrumors regular

    Dale Cooper

    Joined:
    Sep 20, 2005
    #3
    Thanks a lot for your reply! Printing newPtr shows new addresses, so a least malloc is working:p But what I wanted to do originally (this was just a test app to figure out the malloc stuff) was to have a loop that reads one line at the time from a file, saves it in a struct and makes a linked list of the structs. Is it possible to make this idea work?

    Code:
    struct Item *newPtr;
    
    while (fileHasNextLine) {
        newPtr = malloc(sizeof(struct Item));
        struct Item new = *newPtr;
        new.thisLine = fgets(nextLineInFile);
        new.nextLine = previous;
        previous = new;
    }
    
     
  4. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #4
    This is definitely possible, but your approach is just a bit off. I don't want to implement the whole thing for you, but i'll give you some general tips:
    Anything you want to do with an address from the heap that you get using malloc needs to be assigned to a pointer. Any stack-local structs cannot use these addresses. So you'd need:
    A struct Item * for the base of your doubly-linked list.
    A struct Item * for the most recent item you've added (so you can set the next pointer from this Item to a new Item that's being added, and set your new item's previous value to the address of this previous item)
    A struct Item * for the current node you are adding. You should call malloc, and assign the address returned to this value. This might not be needed if you just use the "next" pointer from an existing one to hold this value.

    So, in pseudocode:

    Code:
    Item *base, *last
    base = malloc...
    last = base
    base->previous = NULL;
    while(something_to_do) {
      last->value = get_next_value(&something_to_do)
      last->next = malloc...
      last->next->previous = last
      last->next->next = NULL
      last=last->next
    }
    last->previous->next=NULL //The last thing added didn't get a value
    free((void *)last)
    There's some error checking for 0 length lists, etc. that needs to be done, but you can work that out.

    -Lee
     
  5. Dale Cooper thread starter macrumors regular

    Dale Cooper

    Joined:
    Sep 20, 2005
    #5
    Thanks! Tried you suggestiong, except for a singly linked list, but I could get it to work this time either.

    Code:
    void makeList(int k) {
        int j;
        
    	struct Item *head, *current;
    	head = malloc(sizeof(struct Item)); //allocate memory for first item
    	current = head;
    
        for (j = 0; j < k; j++) {
        	current->number = j; 
                 //set properties for current item
    
            current->next = malloc(sizeof(struct Item));
                 //allocate memory for next item in list
    
            current = current->next; 
                 //set current to the next item in the list		
    		
    	printf("Number: %d, address: %p\n", j, &current);
        }
    
    The output is still
    Number: 0, address: 0x7fff5fbffa98
    Number: 1, address: 0x7fff5fbffa98
    Number: 2, address: 0x7fff5fbffa98
     
  6. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #6
    current is a pointer... so "current" in code is the address this variable is holding, "&current" is the address in memory where current's value is held, and "*current" is dereferencing the pointer assigned to current and evaluates to an Item.

    Print "current" not "&current".

    -Lee
     
  7. Dale Cooper thread starter macrumors regular

    Dale Cooper

    Joined:
    Sep 20, 2005

Share This Page