Yes, a memory leak program because it allocates objects and then loses references to them.
The first time this happens on a line:
x(&test, "etc");
The variable test contains a single copy of the pointer that was allocated during the previous call to x . A new call x overwrites this pointer. At this point, the pointer flows.
This is what a memory leak means: to lose all references to an existing dynamically allocated piece of memory .
The second leak occurs when the main function returns. At this point, the variable test is destroyed, and this variable contains a single copy of duplicate of the pointer on the line "etc" .
Sometimes in C programs we sometimes donβt care about leaks of this second type: memory that is not freed when the program terminates, but it is not allocated again and again in the loop (so this does not cause a memory growth problem).
If a program is ever integrated into another program (for example, as a shared library), where the original main function becomes a launch function that can be called repeatedly in the same program environment, both leaks will turn into problems.
The POSIX strdup function behaves similarly to this:
char *strdup(const char *orig) { size_t bytes = strlen(orig) + 1; char *copy = malloc(bytes); if (copy != 0) memcpy(copy, orig, bytes); return copy; }
Yes; every time he allocates a new repository.
If your image C has a garbage collector (e.g. Boehm), then it is possible that the leaked storage is recycled, and therefore strdup can reuse the same memory for a second allocation. (However, the garbage collector is not going to kick after just one distribution, unless it works in stress test mode to fix errors.)
Now, if you want to reuse memory with realloc, you can change your x function in the following lines:
#include <stdlib.h> #include <string.h> void *strealloc(char *origptr, char *strdata) { size_t nbytes = strlen(strdata) + 1; char *newptr = (char *) realloc(origptr, nbytes); /* cast needed for C++ */ if (newptr) memcpy(newptr, strdata, nbytes); return newptr; }
(By the way, external names starting with str are in the reserved ISO C namespace, but strealloc too nice a name for failure.)
Please note that the interface is different. We do not pass a pointer to a pointer, but instead represent the realloc interface. The caller can check the return value for NULL in order to detect a distribution error, without specifying in this case a pointer inconveniently overwritten with zero.
The main function now looks like this:
int main(void) { char *test = strealloc(NULL, "abcd"); test = strealloc(test, "etc"); free(test); return 0; }
As before, there is no error checking. If the first strealloc should have failed, then test is zero. This is not the case since it is overwritten anyway, and the first argument to strealloc may be null.
Only one free is required to connect a memory leak.