views:

101

answers:

4

Below, I wrote a primitive singly linked list in C. Function "addEditNode" MUST receive a pointer by value, which, I am guessing, means we can edit the data of the pointer but can not point it to something else. If I allocate memory using malloc in "addEditNode", when the function returns, can I see the contents of first->next ? Second question is do I have to free first->next or is it only first that I should free? I am running into segmentation faults on Linux.

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

typedef struct list_node list_node_t;

struct list_node
{ 
  int value;
  list_node_t *next;
};

void addEditNode(list_node_t *node)
{
   node->value = 10;
   node->next =  (list_node_t*) malloc(sizeof(list_node_t));
   node->next->value = 1;
   node->next->next = NULL; 
}

int main()
{
  list_node_t *first = (list_node_t*) malloc(sizeof(list_node_t));

  first->value = 1;
  first->next = NULL;

  addEditNode(first);

  free(first);

  return 0;
}
A: 

First, yes you can "see" the contents of first->next when the function returns. node->next is a value in the struct pointed to by node, which points to the same place as first. When passing the first pointer by value, only the pointer itself is copied, not the whole structure it points to. In other words, *first in main is exactly the same data as *node in addEditNode (not a copy), it's just that each function has a different pointer (one called first and one called node) that point to that one structure.

Second, yes you must free node->next as well or you will have a leak. When you free a pointer to a structure, it does not recursively free pointers that are members of that structure.

However, I don't see anything in that code that is incorrect or that should cause a segmentation fault (a leak won't cause a segfault).

Tyler McHenry
+1  A: 

If I allocate memory using malloc in "addEditNode", when the function returns, can I see the contents of first->next ?

Yes, you can see it in main.

Second question is do I have to free first->next or is it only first that I should free?

You should also free first->next, otherwise you get a memory leak.

A segmentation fault you may get if you try to dereference first after disposing it.

Note however, that removing a node from the linked list also requires rearranging the pointers to keep the list in a valid state. You should write a separate function for this.

Péter Török
+2  A: 

.. means we can edit the data of the pointer but can not point it to something else...

Yes

If I allocate memory using malloc in "addEditNode", when the function returns, can I see the contents of first->next ?

Yes. The memory is allocated on the heap, so you can access it. Note that you are still responsible for freeing the memory.

Second question is do I have to free first->next or is it only first that I should free?

Yes. You are supposed to free all memory allocated on the heap.


Although, there is a memory leak (first->next not freed), but you probably should not get seg-fault.

Note:

node->next =  (list_node_t*) malloc(sizeof(list_node_t));

Explicit casting is not required in case of malloc in C (required in C++). The following is just fine.

node->next = malloc(sizeof(list_node_t));
N 1.1
A: 

A pointer is an integer which designates an address in memory. The details of 'memory' are left unstated here; just know that a pointer contains a number which is an absolute byte in your program's address space.

When you pass a pointer therefore, you pass an address. So by editing the data at the address, you cause your changes to be made visible outside of the local function. So yes, you will see the changes made within addEditNode() in main().

When you dynamically allocate memory, you should always free it. Changes made to the heap are global to the program.