Memory Allocation
From: http://www.lysator.liu.se/c/c-faq/c-3.html
Section 3. Memory Allocation
3.1: Why doesn't this fragment work?
char *answer;
printf("Type something:\n");
gets(answer);
printf("You typed \"%s\"\n", answer);
The pointer variable "answer," which is handed to the gets function as the
location into which the response should be stored, has not been set to point
to any valid storage. That is, we cannot say where the pointer "answer"
points. (Since local variables are not initialized, and typically contain
garbage, it is not even guaranteed that "answer" starts out as a null
pointer. See question 17.1.)
The simplest way to correct the question-asking program is to use a local
array, instead of a pointer, and let the compiler worry about allocation:
#include
char answer[100], *p;
printf("Type something:\n");
fgets(answer, sizeof(answer), stdin);
if((p = strchr(answer, '\n')) != NULL)
*p = '\0';
printf("You typed \"%s\"\n", answer);
Note that this example also uses fgets() instead of gets() (always a good
idea; see question 11.6), allowing the size of the array to be specified, so
that the end of the array will not be overwritten if the user types an
overly-long line. (Unfortunately for this example, fgets() does not
automatically delete the trailing \n, as gets() would.) It would also be
possible to use malloc() to allocate the answer buffer.
3.2: I can't get strcat to work. I tried
char *s1 = "Hello, ";
char *s2 = "world!";
char *s3 = strcat(s1, s2);
but I got strange results.
Again, the problem is that space for the concatenated result is not properly
allocated. C does not provide an automatically- managed string type. C
compilers only allocate memory for objects explicitly mentioned in the
source code (in the case of "strings," this includes character arrays and
string literals). The programmer must arrange (explicitly) for sufficient
space for the results of run-time operations such as string concatenation,
typically by declaring arrays, or by calling malloc. (See also question
17.20.)
strcat performs no allocation; the second string is appended to the first
one, in place. Therefore, one fix would be to declare the first string as
an array with sufficient space:
char s1[20] = "Hello, ";
Since strcat returns the value of its first argument (s1, in this case), the
s3 variable is superfluous.
References: CT&P Sec. 3.2 p. 32.
3.3: But the man page for strcat says that it takes two char *'s as arguments. How am I supposed to know to allocate things?
In general, when using pointers you always have to consider memory allocation, at least to make sure that the compiler is doing it for you. If a library routine's documentation does not explicitly mention allocation, it is usually the caller's problem.
The Synopsis section at the top of a Unix-style man page can be misleading. The code fragments presented there are closer to the function definition used by the call's implementor than the invocation used by the caller. In particular, many routines which accept pointers (e.g. to structs or strings), are usually called with the address of some object (a struct, or an array -- see questions 2.3 and 2.4.) Another common example is stat().
3.4: I have a function that is supposed to return a string, but when it returns to its caller, the returned string is garbage.
Make sure that the memory to which the function returns a pointer is correctly allocated. The returned pointer should be to a statically-allocated buffer, or to a buffer passed in by the caller, or to memory obtained with malloc(), but not to a local (auto) array. In other words, never do something like
char *f()
{
char buf[10];
/* ... */
return buf;
}
One fix (which is imperfect, especially if f() is called recursively, or if
several of its return values are needed simultaneously) would to to declare
the buffer as
static char buf[10];
See also question 17.5.
3.5: Why does some code carefully cast the values returned by malloc to the
pointer type being allocated?
Before ANSI/ISO Standard C introduced the void * generic pointer type, these
casts were typically required to silence warnings about assignment between
incompatible pointer types. (Under ANSI/ISO Standard C, these casts are not
required.)
3.6: You can't use dynamically-allocated memory after you free it, can you?
No. Some early documentation for malloc stated that the contents of freed
memory was "left undisturbed;" this ill-advised guarantee was never
universal and is not required by ANSI.
Few programmers would use the contents of freed memory deliberately, but it
is easy to do so accidentally. Consider the following (correct) code for
freeing a singly-linked list:
struct list *listp, *nextp;
for(listp = base; listp != NULL; listp = nextp) {
nextp = listp->next;
free((char *)listp);
}
and notice what would happen if the more-obvious loop iteration expression
listp = listp->next were used, without the temporary nextp pointer.
References: ANSI Rationale Sec. 4.10.3.2 p. 102; CT&P Sec. 7.10 p. 95.
3.7: How does free() know how many bytes to free?
The malloc/free package remembers the size of each block it allocates and returns, so it is not necessary to remind it of the size when freeing.
3.8: So can I query the malloc package to find out how big an allocated block is?
Not portably.
3.9: I'm allocating structures which contain pointers to other dynamically-allocated objects. When I free a structure, do I have to free each subsidiary pointer first?
Yes. In general, you must arrange that each pointer returned from malloc be individually passed to free, exactly once (if it is freed at all).
3.10: I have a program which mallocs but then frees a lot of memory, but memory usage (as reported by ps) doesn't seem to go back down.
Most implementations of malloc/free do not return freed memory to the operating system (if there is one), but merely make it available for future malloc calls within the same process.
3.11: Must I free allocated memory before the program exits?
You shouldn't have to. A real operating system definitively reclaims all memory when a program exits. Nevertheless, some personal computers are said not to reliably recover memory, and all that can be inferred from the ANSI/ISO C Standard is that it is a "quality of implementation issue."
References: ANSI Sec. 4.10.3.2 .
3.12: Is it legal to pass a null pointer as the first argument to realloc()? Why would you want to?
ANSI C sanctions this usage (and the related realloc(..., 0), which frees), but several earlier implementations do not support it, so it is not widely portable. Passing an initially-null pointer to realloc can make it easier to write a self-starting incremental allocation algorithm.
References: ANSI Sec. 4.10.3.4 .
3.13: What is the difference between calloc and malloc? Is it safe to use calloc's zero-fill guarantee for pointer and floating-point values? Does free work on memory allocated with calloc, or do you need a cfree?
calloc(m, n) is essentially equivalent to
p = malloc(m * n);
memset(p, 0, m * n);
The zero fill is all-bits-zero, and does not therefore guarantee useful zero
values for pointers (see section 1 of this list) or floating-point values.
free can (and should) be used to free the memory allocated by calloc.
References: ANSI Secs. 4.10.3 to 4.10.3.2 .
3.14: What is alloca and why is its use discouraged?
alloca allocates memory which is automatically freed when the function which
called alloca returns. That is, memory allocated with alloca is local to a
particular function's "stack frame" or context.
alloca cannot be written portably, and is difficult to implement on machines
without a stack. Its use is problematical (and the obvious implementation
on a stack-based machine fails) when its return value is passed directly to
another function, as in fgets(alloca(100), 100, stdin).
For these reasons, alloca cannot be used in programs which must be widely
portable, no matter how useful it might be.
References: ANSI Rationale Sec. 4.10.3 p. 102.