Exercises:C Struct: Difference between revisions

From COMP15212 Wiki
gravatar Yuron [userbureaucratinterface-adminsysopPHRhYmxlIGNsYXNzPSJ0d3BvcHVwIj48dHI+PHRkIGNsYXNzPSJ0d3BvcHVwLWVudHJ5dGl0bGUiPkdyb3Vwczo8L3RkPjx0ZD51c2VyPGJyIC8+YnVyZWF1Y3JhdDxiciAvPmludGVyZmFjZS1hZG1pbjxiciAvPnN5c29wPGJyIC8+PC90ZD48L3RyPjwvdGFibGU+] (talk | contribs)
m (1 revision imported)
pc>Yuron
No edit summary
Line 13: Line 13:


----
----
This exercise uses principles illustrated in earlier exercises on [[Exercises:C_Addresses|pointers]] and [[Exercises:Dynamic_Memory|memory
This exercise uses principles illustrated in earlier exercises on [[Exercises:C_Addresses|pointers]] and [[Exercises:Dynamic_Memory|memory allocation]] and you should be happy with those principles before proceeding.
allocation]] and you should be happy with
those principles before proceeding.


Start with the code <code>structures.c</code>, which is an example which builds
Start with the code <code>structures.c</code>, which is an example which builds (and then destroys) a <strong>linked list</strong>.  Check you can compile and run it okay.
(and then destroys) a <strong>linked list</strong>.  Check you can compile and run
it okay.


Look at the source code in conjunction with the output.  About 10 lines down a C <code>struct</code> is defined and named as a user-defined type “PCB”.  This is a much simplified illustration of the sort of structure which can be used as a [[Process Control Block (PCB)|process control block]].
Look at the source code in conjunction with the output.  About 10 lines down a C <code>struct</code> is defined and named as a user-defined type “PCB”.  This is a much simplified illustration of the sort of structure which can be used as a [[Process Control Block (PCB)|process control block]].
<blockquote>
<blockquote>
This example starts off containing a couple of <code>int</code> data fields and
This example starts off containing a couple of <code>int</code> data fields and a [[Pointers|pointer]] to any similar structure.
a [[Pointers|pointer]] to any similar structure.
Later you may like to experiment adding some fields of your own to see what is affected.
Later you may like to experiment adding some fields of your own to
see what is affected.
</blockquote>
</blockquote>
This <code>typedef</code> just defines the ‘class’; it does not
This <code>typedef</code> just defines the ‘class’; it does not declare any <em>actual</em> variables.
declare any <em>actual</em> variables.


A bit further down the <code>typedef</code> is used to <em>instantiate</em> a structure – in this case called “dummy”.  Only one instance is made here: the similar looking declarations are (potentially) <em>pointers</em> to such structures.
A bit further down the <code>typedef</code> is used to <em>instantiate</em> a structure – in this case called “dummy”.  Only one instance is made here: the similar looking declarations are (potentially) <em>pointers</em> to such structures.
Line 38: Line 31:
[[Image:linked_list.png|link=|alt=Linked list]]
[[Image:linked_list.png|link=|alt=Linked list]]


“dummy” is mostly not used – only the pointer is
“dummy” is mostly not used – only the pointer is important here … and that’s not used <em>yet</em> which is why it’s set to <code>NULL</code>.
important here … and that’s not used <em>yet</em> which is why it’s set to
<code>NULL</code>.
<blockquote>
<blockquote>
We built it this way because it makes the code a bit shorter (so,
We built it this way because it makes the code a bit shorter (so, maybe, clearer?): there is no need for special-case coding for an
maybe, clearer?): there is no need for special-case coding for an
empty list.
empty list.
 
 
<strong>Syntax</strong>: <code>dummy.pNext</code> (for example) refers to the field <code>pNext</code> in
<strong>Syntax</strong>: <code>dummy.pNext</code> (for example) refers to the field <code>pNext</code> in
the instance.
the instance.
<code>&</code> means “the address of” (remember?) which sets the
<code>&</code> means “the address of” (remember?) which sets the pointer to the end of the list (<code>pEnd</code>) to point at this ‘zero-th’ entry.
pointer to the end of the list (<code>pEnd</code>) to point at this
‘zero-th’ entry.
</blockquote>
</blockquote>
It is useful to establish the size of integers and pointers on the
It is useful to establish the size of integers and pointers on the system you are using.  The code (<code>print_structure()</code>) then prints the (hexadecimal) address of each <em>field</em> in the structure.  Your <strong>drawing</strong> should show that these are spaced the appropriate distances apart.  The <em>absolute</em> values of the addresses don’t really matter at the moment.
system you are using.  The code (<code>print_structure()</code>) then prints the
(hexadecimal) address of each <em>field</em> in the structure.  Your
<strong>drawing</strong> should show that these are spaced the appropriate
distances apart.  The <em>absolute</em> values of the addresses don’t really
matter at the moment.


Skip over <code>print_list()</code> – delete it if you like.  At this point it’s
Skip over <code>print_list()</code> – delete it if you like.  At this point it’s just saying there’s nothing there.  Follow <em>into</em> <code>add_entry()</code> though.
just saying there’s nothing there.  Follow <em>into</em> <code>add_entry()</code>
though.
<blockquote>
<blockquote>
<code>add_entry()</code> takes some data values and makes a new block (<code>struct</code>
<code>add_entry()</code> takes some data values and makes a new block (<code>struct</code> instance) for them.  This involves:
instance) for them.  This involves:


* dynamic allocation of a big enough memory block
* dynamic allocation of a big enough memory block
Line 85: Line 65:
we could write:
we could write:
<code>(*pTemp).pNext</code>
<code>(*pTemp).pNext</code>
which has the same function, although that probably doesn’t make
which has the same function, although that probably doesn’t make things much clearer.
things much clearer.
</blockquote>
</blockquote>
</blockquote>
</blockquote>
</blockquote>
</blockquote>
After that, the code plays (as should you) at adding a few more links
After that, the code plays (as should you) at adding a few more links to the list and printing out the addresses.
to the list and printing out the addresses.
<blockquote>
<blockquote>
A couple of things to observe, although different systems will vary:
A couple of things to observe, although different systems will vary:
Line 99: Line 77:


</blockquote>
</blockquote>
Lastly, the list is stripped down and disposed of, block by block,
Lastly, the list is stripped down and disposed of, block by block, using the <code>free()</code> call.  This is Good Practice even though the operating system will tidy up anyway when the process terminates.
using the <code>free()</code> call.  This is Good Practice even though the
operating system will tidy up anyway when the process terminates.


=== Puzzle ===
=== Puzzle ===
You <em>may</em> see that the malloc elements are <em>almost</em> adjacent but have
You <em>may</em> see that the malloc elements are <em>almost</em> adjacent but have some small gaps between them.  Speculate on why this might be. (This is quite difficult so don’t panic if you can’t think of anything.)
some small gaps between them.  Speculate on why this might be.
(This is quite difficult so don’t panic if you can’t think of anything.)
----
 
=== Submission ===
 
*A <em>text</em> figure showing the addresses and corresponding data of the data structures involved, at its fullest extent.<br /> (Hint - don’t add <em>too</em> many more records!)<br /> Something like this example (from a real, 32-bit x86 Linux system):  [[Image:Ex_struct_ans.png|link=|alt=Example answer]]
*If you have any thoughts on the puzzle, append them, too.
 
<em>For convenience, please amalgamate these into a single text file</em> [<code>ex4.txt</code>].
----
----
{{PageGraph}}
{{PageGraph}}
{{Category|Exercises}}
{{Category|Exercises}}

Revision as of 10:24, 8 August 2019

On path: Exercises 0: Exercises • 1: Pointer Exercise • 2: Arguments Exercise • 3: Malloc Exercise • 4: Structs Exercise • 5: Processes Exercise • 6: Shared memory Exercise • 7: Pipes Exercise • 8: Exceptions Exercise • 9: Synchronisation Exercise • 10: Files Exercise • 11: Threads Exercise • 12: Unix proc Exercise
On path: Pointers 1: Memory • 2: Arrays • 3: Pointers • 4: Pointer Exercise • 5: Structures • 6: Dynamic Memory Allocation • 7: Malloc Exercise • 8: Structs Exercise
Depends on Dynamic Memory AllocationMemory

Download exercise files

The purposes of this exercise are:

  • to augment understanding of memory layout
  • to illustrate an example of the type of structures used in operating system functions
  • to introduce some (confusing?) C language syntax
  • to introduce dynamic memory allocation (in C)

This exercise uses principles illustrated in earlier exercises on pointers and memory allocation and you should be happy with those principles before proceeding.

Start with the code structures.c, which is an example which builds (and then destroys) a linked list. Check you can compile and run it okay.

Look at the source code in conjunction with the output. About 10 lines down a C struct is defined and named as a user-defined type “PCB”. This is a much simplified illustration of the sort of structure which can be used as a process control block.

This example starts off containing a couple of int data fields and a pointer to any similar structure. Later you may like to experiment adding some fields of your own to see what is affected.

This typedef just defines the ‘class’; it does not declare any actual variables.

A bit further down the typedef is used to instantiate a structure – in this case called “dummy”. Only one instance is made here: the similar looking declarations are (potentially) pointers to such structures.

At this point you might like to start drawing the memory structures. Here’s a bit to get you started.

Linked list

“dummy” is mostly not used – only the pointer is important here … and that’s not used yet which is why it’s set to NULL.

We built it this way because it makes the code a bit shorter (so, maybe, clearer?): there is no need for special-case coding for an empty list.   Syntax: dummy.pNext (for example) refers to the field pNext in the instance. & means “the address of” (remember?) which sets the pointer to the end of the list (pEnd) to point at this ‘zero-th’ entry.

It is useful to establish the size of integers and pointers on the system you are using. The code (print_structure()) then prints the (hexadecimal) address of each field in the structure. Your drawing should show that these are spaced the appropriate distances apart. The absolute values of the addresses don’t really matter at the moment.

Skip over print_list() – delete it if you like. At this point it’s just saying there’s nothing there. Follow into add_entry() though.

add_entry() takes some data values and makes a new block (struct instance) for them. This involves:

  • dynamic allocation of a big enough memory block
  • writing the data into the newly created block
  • making the new block a potential list terminator
  • pointing the current last block at the new block
  • returning a pointer to the (new) last block in the list
     
    Pause to understand that.

Syntax: pTemp->pNext (for example) refers to the field ‘pNext’ in the struct pointed at by pTemp.   Pause to understand that; maybe draw it.  

If you’re insufficiently confused, instead of writing: pTemp->pNext we could write: (*pTemp).pNext which has the same function, although that probably doesn’t make things much clearer.

After that, the code plays (as should you) at adding a few more links to the list and printing out the addresses.

A couple of things to observe, although different systems will vary:

  • The dynamically allocated blocks will probably have addresses close to each other.
  • The dynamically allocated blocks will probably have addresses somewhat different to the statically allocated dummy; this may be in a different segment.

Lastly, the list is stripped down and disposed of, block by block, using the free() call. This is Good Practice even though the operating system will tidy up anyway when the process terminates.

Puzzle

You may see that the malloc elements are almost adjacent but have some small gaps between them. Speculate on why this might be. (This is quite difficult so don’t panic if you can’t think of anything.)