C语言中的动态内存分配

348 阅读3分钟

在DMA中,关于分配内存的决定不能在编译时进行。这种决定或内存是在运行时分配的。

每当我们通过DMA创建任何变量时,这种类型的变量没有任何名称;我们通过地址或指针访问这些变量。

在SMA中,程序员很早就知道他/她的程序需要多少个变量或多少个存储器。

但在DMA中,程序员在早期并不知道需要多少变量或内存,这取决于用户的要求。

DMA的类型。

  1. malloc ()
  2. calloc ()
  3. realloc ()
  4. 释放()

malloc()

当编译器读到这一行时,malloc()函数是一个动作语句。编译器并不了解有多少内存被分配,因为它是一个动作语句。在运行时,内存块被创建。

每当我们调用malloc()时,我们传递一个数字作为参数,它可以理解malloc()要创建的内存块的字节数。在malloc()中,它不能声明任何数据类型。Malloc()总是返回创建内存块的地址。

Malloc()的返回类型是一个空指针,因为它不知道返回哪种类型的地址。为此,我们必须输入caste。

1P = (float*) malloc (4);

这里我们输入了caste,因为malloc()是一个无效指针。

例子-1:

#include<stdio.h>

#include<stdlib.h>

#define NULL 0

int main ()
{
    int *a , *t ;
    int size ;
    printf ( " what is the size of the table ? " ) ;
    scanf("%d",&size);
    printf ( " \n " ) ;
    if ( ( t = ( int* ) malloc ( size * sizeof ( int ) ) )  == NULL )
    {
    printf( " No space available \n " ) ;
    exit ( 1 ) ;
    }
    printf ( " \n Address of the first byte is %u\n " , t ) ;
    /* Reading table values*/
    printf ( " \n Input table values \n " ) ;
    for ( a = t ; a < t + size ; a++ )
    scanf("%d", a);
    /* Printing table values in reverse order*/
    for ( a = t + size - 1 ; a >= t ; a -- )
    printf ( " %d is stored at address %u \n ", *a , a ) ;
    free ( t ) ;
    return 0 ;

输出。

Calloc ()。

在calloc()的帮助下,我们可以在calloc中创建多个块或数组(我们传递两个参数;第一个参数是我们想创建多少个块,第二个参数是块的大小)。calloc()还返回每个块的地址,默认情况下,0是存在的。

例子-2:

#include<stdio.h>

#include<stdlib.h>

int main ()
{
    int *n , *freq , i , size ;
    printf ( " what is the size of the list ? " ) ;
    scanf("%d",&size);
    n = ( int* ) malloc ( size * sizeof( int ) ) ;
    printf ( " Enter the numbers: " ) ;
    for ( i = 0 ; i < size ; i++ )
    {
        printf ( " \n enter the num[%d]: ",i ) ;
        scanf("%d",&n[i]);
        if ( n [ i ] < 0 || n [ i ] > 4 )
            {
                printf ( " \n Number should be within range (0-4) " ) ;
                i-- ;
                continue ;
            }
    }
    freq = ( int * ) calloc ( 5 , sizeof ( int ) ) ;
    for ( i = 0 ; i < size ; i++ )
            freq [ n [ i ] ]++ ;
    printf ( " \n The frequencies of the numbers are: " ) ;
    for ( i = 0 ; i < 5 ; i++ )
            printf ( " \n freq [%d] = %d " , i , freq [ i ] ) ;
    printf ( " \n " ) ;
    free ( freq ) ;
    return 0 ;
}

输出。

realloc ()

每当我们在malloc()或calloc()的帮助下创建了一个块,并且我们想改变或调整这个块的大小,我们就使用realloc()。

Void *realloc (void *block, int size)

在realloc()中,我们必须把地址作为一个参数传递给我们想要调整大小的块。

realloc (ptr,8);

和我们要调整的块的大小。这个大小我们必须在realloc()中传递一个参数。

double *q;

q=realloc (ptr,8);

只有那些由malloc()或calloc()创建的块才能被realloc()调整大小。

例子-3:

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#define NULL 0

int main()

{

char *buffer ;

/* Allocating memory */

if ( ( buffer = ( char * ) malloc ( 10 ) ) == NULL )

{

printf (" malloc failed. \n " ) ;

exit ( 1 ) ;

}

printf ( " Buffer of size %d created \n " , sizeof (buffer) );

strcpy ( buffer , " HYDERABAD " ) ;

printf( " \n Buffer contains: %s \n " , buffer ) ;

/* Reallocation */

if ( ( buffer = ( char * ) realloc ( buffer , 15 ) ) == NULL )

{

printf ( " Reallocation failed. \n " ) ;

exit ( 1 ) ;

}

printf ( " \n Buffer size modified. \n " ) ;

printf ( " \n Buffer still contains: %s \n " , buffer ) ;

strcpy ( buffer , " SECUNDERABAD " ) ;

printf ( " \n Buffer now contains: %s \n " , buffer ) ;

/* Freeing memory */

free ( buffer ) ;

return 0 ;

}

输出。

free ()

在free()的帮助下,我们释放由malloc()或calloc()或realloc()创建的内存块。

静态变量只存在于块或函数的范围内。如果我们不能运行free(),只要静态变量p被销毁,动态创建的变量就不会被销毁,而是永远留在RAM或内存中。这就是所谓的内存泄漏。为此,free()需要销毁动态创建的内存块。

Free()只销毁那些动态创建的内存。

总结。

DMA是C语言中一个强大的概念,因为它消除了SMA的缺点。在SMA中,我们必须在运行程序之前决定创建多少个内存块。结果,内存被浪费了,或者内存不够用。DMA通过在运行时决定需要分配多少块内存来解决这个问题。它根据程序的要求来分配内存。