How to be a better C programmer?

I

istillshine

Thanks.

- matching your resource allocations with deallocations

Do I have to match each malloc() with a free()? It is easy to omit a
few free()'s, but the program still works. I know it is not a good
idea not to free resources.
Is there any method to ensure each malloc() is accompanied by a
free()?
- adding error logs for situations that are checked but

I don't know how to this. Can you give more details?
- following the coding guidelines

What are the coding guidelines?
 
A

Antoninus Twink

Is there any method to ensure each malloc() is accompanied by a
free()?

There are many leak-detection programs available. A really excellent one
for Linux and BSD is valgrind.
 
J

jxh

Do I have to match each malloc() with a free()? It is easy to
omit a few free()'s, but the program still works. I know it is
not a good idea not to free resources. Is there any method to
ensure each malloc() is accompanied by a free()?

The point of becoming detail oriented is to pay attention when
you use resource allocation and match it with a deallocation.
You want to avoid creating a resource leaks instead of spending
time to debug them.

There are many types of resources. In C, there are memory, files,
and variable argument lists that have APIs to allocate and
deallocate. C APIs outside of C proper introduce many more types
of resources. Avoiding resource leaks is best accomplished by
vigilantly checking each allocation is accompanied with a
deallocation, and such vigilance requires attention to detail.

There are tools to help track down resource leaks (purify, for
instance), but the goal is to write code that doesn't have this
problem in the first place.
I don't know how to this.  Can you give more details?

Error logs typically mean a mechanism that records that
something wrong happened, and that this record can be
consulted when you discover that your program has a bug.
Typically, this means a file that is written to, but it
doesn't have to be. In C, some kind of call to fprintf
can serve to log errors to a file.
What are the coding guidelines?

These are typically supplied by your employer, or is
dictated by the chaperones of the code base you are
modifying or extending. They typically govern coding
style. I can usually peg a novice as being detail
oriented or not by whether their coding style matches
the coding style of the rest of the file to with they
were tasked with adding some code.

-- James
 
S

santosh

Thanks.



Do I have to match each malloc() with a free()?

If you're interested in robust code, yes. Admittedly most modern
operating systems reclaim all of the programs memory after the latter
terminates, but some programs like servers and daemons don't terminate
(to be precise, they run for a long time), so deallocating memory when
you have finished using it will allow your malloc implementation to, if
needed, return the memory to the system. This allows other programs to
use it and also keeps the total memory consumption of your program to
reasonable levels.

As you would probably have noticed most applications don't do this, but
that's no reason to imitate such practises.
Is there any method to ensure each malloc() is accompanied by a
free()?

If you mean an automated method, then no. C leaves that task completely
to the programmer. This gives great flexibility but it also requires
careful attention to details.

If you don't mind a reduction in portability then you might consider
using a Garbage Collector. A well respected one for C is the Boehm GC
(http://www.hpl.hp.com/personal/Hans_Boehm/gc/).
I don't know how to this. Can you give more details?

In general logging means that your program periodically saves
information and/or state to some form of permanent storage, to enable
programmers, system administrators, and users to study the execution of
the program and any problems it encounters. Many programs have their
own logging routines (or a secondary program for that purpose), but you
can also use something like syslog (http://www.syslog.org/).
What are the coding guidelines?

<http://en.wikipedia.org/wiki/Code_conventions>
<http://en.wikipedia.org/wiki/Programming_style>
 
I

istillshine

santosh said:


Thanks. I examined the NetBSD coding guidelines and liked it. I
don't not understand
the following statement though, particularly "and not depend on the
including file for that header including both" in the first sentence.

/*
* If a header file requires structures, defines, typedefs, etc. from
* another header file it should include that header file and not
depend
* on the including file for that header including both. If there are
* exceptions to this for specific headers it should be clearly
documented
* in the headers and, if appropriate, the documentation. Nothing in
this
* rule should suggest relaxation of the multiple inclusion rule and
the
* application programmer should be free to include both regardless.
*/
 
I

istillshine


Thanks. I checked the NetBSD coding guidelines and liked them. I
don't understand the following statement though, particularly "and not
depend on the including file for that header including both" in the
first sentence.
What dose it mean?

/*
* If a header file requires structures, defines, typedefs, etc. from
* another header file it should include that header file and not
depend
* on the including file for that header including both. If there are
* exceptions to this for specific headers it should be clearly
documented
* in the headers and, if appropriate, the documentation. Nothing in
this
* rule should suggest relaxation of the multiple inclusion rule and
the
* application programmer should be free to include both regardless.
*/
 
I

Ian Collins

Thanks. I examined the NetBSD coding guidelines and liked it. I
don't not understand
the following statement though, particularly "and not depend on the
including file for that header including both" in the first sentence.
All it is saying is that headers should be self contained. If header x
uses something declared in header y it should include it, rather than
the user of header x having to include both x and y. This is a common,
but not universal, guideline.
 
I

istillshine

All it is saying is that headers should be self contained. If header x
uses something declared in header y it should include it, rather than
the user of header x having to include both x and y. This is a common,
but not universal, guideline.

I really learned something useful from the NetBSD style guide. But
why doesn't it allow
initialize variables' values in their declarations? I do that often.

/*
* When declaring variables in functions declare them sorted by size,
* then in alphabetical order; multiple ones per line are okay.
* Function prototypes should go in the include file "extern.h".
* If a line overflows reuse the type keyword.
*
* DO NOT initialize variables in the declarations.
*/
 
I

Ian Collins

I really learned something useful from the NetBSD style guide. But
why doesn't it allow
initialize variables' values in their declarations? I do that often.

That's a very contentions rule. I always try and introduce variables
when they can be initialised and not before.
 
J

jxh

If you're interested in robust code, yes. Admittedly most
modern operating systems reclaim all of the programs memory
after the latter terminates, but some programs like servers and
daemons don't terminate (to be precise, they run for a long
time), so deallocating memory when you have finished using it
will allow your malloc implementation to, if needed, return
the memory to the system. This allows other programs to use it
and also keeps the total memory consumption of your program to
reasonable levels.

There are some types of resources which will not be reclaimed
after the program terminates, and other types for which no
tools exist to track their utilization, and are not associated
with memory that can be garbage collected. That is why I
emphasized the notion of resource rather than memory.

To give an example: Suppose there is a program that
continuously writes data to a file until the file has reached a
certain size. At that point, the program opens a new file and
the operation iterates.

As specified above, there are (at least) two problems:
- The program never closes the files it opens. On many systems
this will cause the program to eventually be unable to open
a file (and may cause any other program on the same system
to be unable to open a file as well).
- The medium on which the files reside is unlikely to have
infinite capacity. When the medium reaches capacity, the
program (and likely the entire system) will fail. This
problem would exist even if the program was fixed to close
the file it had previously opened.

-- James
 
C

Chad

I personally like C, and do not like any OO languages.  The reference
books for OO languages are too heavy for me.  They just made things
complicated.  Someone laughed at my opinion, saying Google code bases
are mostly written in C++.

I read somewhere about the best way to learn C (or a programming
language in general).   I agree with the points.  I quote them below:

"The best way to do it is to read some stuff written by masters of the
form, write some things yourself, read a lot more, write a little
more, read a lot more, write some more ... and repeat until your
writing begins to develop the kind of strength and economy you see in
your models."

For C books, I have carefully read The C Programming Language, The C
Answer Book, and The C Puzzle Book.  For real C code, I have carefully
read about 20,000 lines written by UC Berkeley guys.  I myself have
written about 15,000 lines, not counting tiny toy programs.  It is my
situation.

My question is where I can find "some stuff written by masters of the
form" ?  I think BSD source code is written by masters.  Am I right?


I really wouldn't use 20,000 lines written by UC Berkeley guys as any
kind of benchmark. Let me explain. Once upon a time a person that
barely passed high school could have gone to the local community
college, taken a bunch of classes to improve their GPA and then could
have transferred into UC-Berkeley. I'm pretty sure a few them them
probably became computer science majors. A person that wasn't aware of
this process would be inclined to automatically assume the person that
wrote the C code had to be a brilliant because they went to UC-
Berkeley. When in reality, it was just some person that knew how to
play the 'college game.'

However, this is no longer the case. A few years ago UC-Berkeley
finally stopped admitting people that went to the local community
college to improve their GPA.
 
I

Ian Collins

CBFalconer said:
Simple. Declaring and initializing a variable makes it exist. If
you include the header in two or more files used in your program
the variable is multi-defined, and there is a linkage error.
Note the words "declaring variables in functions". Defining a function
in a header and including the header in two or more files used in your
program will cause a linkage error.
 
N

Nick Keighley

The easiest way is to write code of the form:

   if (!(p = malloc(N * sizeof *p)) correct_the_fault(p);
   ....
   /* code using p */
   ....
   free(p);

yes, but simpler would be

P_type p;
/* code using p */

:)

The only reason to use malloc() with code like this if your
implementation allows dynamic objects to be larger than automatic
objects. Or your stack (hello trolls!) is small.

A likely reason for dynamic data is where allocation and freeing
are widely separated or statically unpredictable (eg. event driven).

Or the number or size of objects is unpredicable.

which may nor always be suitable to the rest of your logic.  Then
you have to look at other methods, such as lists, arrays, etc.  But
the above will certainly work.

yes you then neen lists or arrays or whatever.

One trick to isolate the memory management in a separate "module".

Ultimately there is no replacement for care.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,297
Messages
2,571,536
Members
48,282
Latest member
Xyprime

Latest Threads

Top