[NSWI004] Comments for A00 (printf and lists)

Vojtech Horky horky at d3s.mff.cuni.cz
Wed Oct 14 13:43:37 CEST 2020


Hello,

I will be uploading comments for A00 assignment to your grading 
repository shortly.

This assignment was not graded (please, do not worry about the 0 
points); we provide feedback as comments of your source code.


Generally, the solutions were rather nice and most of you submitted the 
extended assignment too.


A lot of the comments are related to style. Do not take them as strict 
orders how to do things but rather as thoughts on how to do things 
differently (and perhaps better in the long term).

The keyword that was inherent to many solutions was *consistency*. Be 
consistent in how you name things, how you format your code and avoid 
surprises. Such surprises include hiding statements on the same line as 
the "if" that are followed by badly indented line or functions that have 
side effects one would not expect.


Basically only one type of functional error was present in more 
solutions - insufficient handling of dynamic memory allocations. Follows 
a short description of each issue.

We acknowledge that handling these issues below is not trivial. The C 
language does not have exceptions, destructors etc. and one has to be 
extra careful. But don't be scared :-)

Here are the three typical issues.

(1) Not checking that `malloc` returned a valid memory (i.e. non NULL). 
This is something unheard of in languages with managed memory and you 
would typically not encounter such situations in C anyway. Unless you 
move into kernel. You will see that running out of memory is quite a 
normal situation and you should prepare your code for that.

Note that proper response is to return NULL or ENOMEM or similar, not to 
halt your application. Allow the caller to decide what to do.

(2) Leaking memory. Either by not freeing all items of a list or in more 
subtle situations like the one below.

void *ptr1 = malloc(..);
if (ptr1 == NULL) { return NULL; }
void *ptr2 = malloc(...);
if (ptr2 == NULL) { return NULL; }

This code leaks memory of ptr1 if the second allocation fails. Correct 
approach is to add free(ptr1) the second "if" or use error gotos as are 
for example used in Linux [1].

[1] 
https://github.com/torvalds/linux/blob/156c05917e0920ef5643eb54c0ea71aae5d60c3d/tools/testing/selftests/cgroup/test_memcontrol.c#L27

(3) Memory corruption by using memory after freeing it. Following 
pseudo-code for linked list deallocation is not correct although it will 
probably run without any issues in many environments.

while (it != NULL) {
    free(it);
    it = it->next;
}

Please not that (2) is not something inherent to C. It would not happen 
in managed languages with memory but it can easily happen with other 
resources. Such as opened files, network connections or database cursors.


If you have any questions regarding the comments, please, e-mail us. 
Preferably off-list, we can forward to the list explanations that were 
not unique to your implementation.

Cheers,
- VH


More information about the NSWI004 mailing list