In C, you've thought about creating variables to be used in your program. You have created some arrays to be used, but you may have noticed some limitations:
- The size of the array must be known in advance
- The size of the array cannot be changed for the duration of the program
C inDynamic Memory Allocationis a way to circumvent these problems.
(used form a nominal expression)mallocfunction (math.)
#include <stdlib.h> void * calloc (size_t nmemb , size_t size ); void free (void * ptr ); void * malloc (size_t size ); void * malloc (size_t size )
Standard C function (math.)mallocis a means of implementing dynamic memory allocation. It is defined in either stdlib.h or malloc.h, depending on the operating system you may be using. malloc.h contains only the definitions of the memory allocation functions, not the definitions of the other functions defined in stdlib.h. Usually you don't need to be so specific in your program, and if both are supported you should use , since that is ANSI C, which is what we will be using here.
The corresponding call to free allocated memory back to the operating system is thefreeThe
When dynamically allocated memory is no longer needed, thefreeIt should be called to free it back into the memory pool. Overwriting a pointer to dynamically allocated memory may cause that data to become inaccessible. If this happens frequently, eventually the operating system will not be able to allocate any more memory for the process. Once the process exits, the operating system is able to free all dynamically allocated memory associated with that process.
Let's see how dynamic memory allocation can be used for arrays.
Typically, when we wish to create an array, we use a declaration such as
int array [ 10 ];
recall (a product, an ambassador etc)arraycan be thought of as a pointer that we use as an array. We specify the length of this array as 10 ints. After that.array[0], the other nine integers have space for continuous storage.
Sometimes when writing a program it is not known how much memory is required for certain data. In this case, we want to dynamically allocate the required memory after the program starts executing. To do this, we just need to declare a pointer andmallocCalled when we want to make room for an element in an array, theorWe can tellmallocThe space is created when the array is first initialized. Both are acceptable and useful.
We also need to know how much int is taking up in memory in order to make room for it; fortunately, this is not difficult and we can use C's built-insizeofoperators. For example, ifsizeof(int)With a yield of 4, ainttakes up 4 bytes. Of course.2*sizeof(int)How much memory do we need? intseconds, and so on.
So how can we use it like we used tomalloc10intHow many arrays? If we want to declare and free up space in one strike, we can simply say
int * array = malloc (10 *) sizeof (int )).
We only need to declare the pointer; the mallocGive us some space to store 10 intseconds and returns a pointer to the first element to which it is assigned.
Important Tip! mallocfurthermorehasn'tInitialize the array; this means that the array may contain random or unexpected values! Just like creating arrays without dynamic allocation, the programmer must initialize the array with sensible values before using it. Always make sure you do this. (Take a look at this function latermemsetof simple methods.)
mallocIt is not necessary to call a pointer immediately after declaring it for allocated memory. There are usually a number of statements between the declaration and the callmalloc, as shown below:
int * array = NULL ;
printf ("Hello World !!!" ) ;
/ * more statements * /
array = malloc (10 *) sizeof (int )). / *Delayed allocation* /
/ *Use of arrays* /
error checking
When we want to usemalloc, we must note that the pool of memory available to the programmer isrestricted. Therefore, we can imagine a lack of memory! In this case.mallocwill returnNULL. To stop the program from crashing and no longer using memory, one shouldNULLAlways check that malloc has not returned before trying to use memory; we can do this
int * pt = malloc (3 *) sizeof (int )).
if (pt == NULL )
{
fprintf (stderr , "Out of memory, exiting \ n " );
Exit (1 );
}
Of course, an abrupt exit in the above example is not always appropriate and depends on the problem you are trying to solve and the architecture you are programming. For example, if the program is a small, non-critical application, it may be appropriate to run it on desktop exit. However, if the program is some type of editor that runs on the desktop, you may want to give the operator the option of saving the information he or she tediously enters rather than just exiting the program. Memory allocation failures in embedded processors (such as might be found in a washing machine) can result in an automatic reset of the machine. For this reason, many embedded system designers avoid dynamic memory allocation altogether.
(used form a nominal expression)callocfunction (math.)
ought tocallocfunction allocates space for an array of items and initializes the memory to zero. Calling themArray = calloc( count, sizeof(struct V))allocatecountobjects, each of which is large enough to contain instances of the structurestruct V. The space is initialized to all bits zero. The function returns a pointer to the allocated memory or, if allocation failed, theNULLThe
(used form a nominal expression)reallocfunction (math.)
void * realloc (void * ptr , size_t size );
ought toreallocfunction changes the size of the object pointed to toptrSpecified sizesize. The contents of the object shall remain unchanged until the smaller of the old or new size. If the new size is larger, the value of the newly assigned portion of the object is indeterminate. If theptris a null pointer, then thereallocThe behavior of the function is similar to that of themallocfunction of the specified size. Otherwise, if theptrMismatched pointers returned earliercalloc(math.) genusmallocmaybereallocfunction, or if the space has come to a call to releasefreemaybereallocfunction, the behavior is indeterminate. If space cannot be allocated, the object pointed toptrNo change. If thesizezero-sum (math.)ptris not a null pointer and the object it points to is released. ThereallocThe function returns a null pointer or a pointer to an allocated object that may have moved.
(used form a nominal expression)freefunction (math.)
Already usedmalloc(math.) genusreallocmaybecallocMemory must be freed back into the system memory pool when it is no longer needed. This is done to avoid permanently allocating more and more memory, which could lead to eventual memory allocation failures.freeHowever, the current program will free unreleased memory when it terminates on most operating systems. CallfreeAs shown in the example below.
int * myStuff = malloc (20 *) sizeof (int )).
if (myStuff ! = NULL )
{
/ *More statements* /
/ * time to release myStuff * /
free (myStuff ); }
}
Free Recursive Data Structures
worthy of notefreeis neither smart nor recursive. The following code relies on free's recursive application for the pair offrameworkThe internal variables do not work.
typedef struct BSTNode
{
int value ;
struct BSTNode * left ;
struct BSTNode * right ;
} BSTNode ;
// Later: ......
BSTNode * temp = (BSTNode * ) calloc (1 , ) sizeof (BSTNode )); temp - > left = (BSTNode * ) calloc (1)
temp - > left = (BSTNode * ) calloc (1 , ) sizeof (BSTNode )).
// Later: ......
Free (temporary). // Re! Don't do it!
Statement." free(temp);" will not (act, happen etc)liberate (a prisoner)temp->leftthat leads to memory leaks. The correct way to do this is to define a way to free the memory in the data structure of theeveryonefunction of the node:
void BSTFree (BSTNode * node ){
if (node ! = NULL ) {
BSTFree (node - > left);
BSTFree (node -> right );
free (node ).
}
}
Because C does not have a garbage collector, C programmers are responsible for ensuring that thefree()One at a time.malloc(). If one node is assigned to a node at a time, it needs to be released one node at a time.
Do not free undefined pointers
In addition.freeOften crashes or causes further cryptic errors when a faulty pointer is never allocated in the first place.
To avoid this problem, always initialize pointers when you declare them. Eithermallocis used when declaring them (as shown in most of the examples in this chapter), either theNULLSet them when you declare them (in the "Deferred Assignment" example in this chapter). [1]
Write constructor/destructor
One way to get memory initialization and destruction is to mimic object-oriented programming. In this paradigm, objects are constructed after raw memory is allocated for them, over their lives, and when they are destroyed, a special function called a destructor destroys the object's internals before the object itself is destroyed.
Example:
#include / *needs malloc and friends* /
/ * This is the type of object we have, with only one int member * /
typedef struct WIDGET_T {
WIDGET_T ; int member ;
} WIDGET_T ;
/ * Functions that handle WIDGET_T * /
/ *constructor* /
void
WIDGETctor (WIDGET_T * this , int x )
This - > member = x ; this - > member = x ; WIDGET_T
this -> member = x ;
}
/ * destructor * /
void
WIDGETdtor (WIDGET_T * this )
{
/* In this case, I don't really need to do anything but
If WIDGET_T has internal pointers, the objects they point to
will be destroyed here. * /
this - > member = 0 ;
}
/ * create function - this function returns a new WIDGET_T * /
WIDGET_T *
WIDGETcreate (int m )
WIDGET_T * x = 0 ; WIDGET_T
WIDGET_T * x = 0 ;
x = malloc (sizeof (WIDGET_T )).
if (x == 0 )
abort (); / *No memory* /
WIDGETctor (x, m);
come (or go) back x ;
}
/ * destroy function - calls the destructor and then frees the object * /
void
WIDGETdestroy (WIDGET_T * this )
WIDGETdtor (this ); {
WIDGETdtor (this ); .
free (this ); }
}
/ *End code* /
Guess you want to read:Programming in C. Intermediate C" 4. Error Handling



