Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Dale Cooper

macrumors regular
Original poster
Sep 20, 2005
218
0
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...
 
'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.
 
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;
}
 
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
 
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
 
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
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.