为什么呢,或者,你需要在C动态分配内存? [英] Why, or when, do you need to dynamically allocate memory in C?

查看:169
本文介绍了为什么呢,或者,你需要在C动态分配内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

动态内存分配在C编程一个非常重要的课题。不过,我一直无法找到这是什么使我们能够做什么,或者为什么它需要很好的解释。

我们不能只声明变量和结构,并从来没有使用malloc()?

作为一个方面说明,之间有什么区别:

  ptr_one =(INT *)malloc的(的sizeof(INT));

 为int * ptr_one =的malloc(sizeof的(INT));


解决方案

您需要使用动态内存时:


  • 您无法确定的最大内存量在编译时使用;

  • 您想分配的非常的大对象;

  • 您想建立的数据结构(容器)无固定上限大小;

您总是不知道你需要多少内存在编译时备用。想象处理的数据文件(一个时间序列的温度,比方说),其中的记录在文件中的数字是不固定的。你可以有少至10个记录或多达100000如果你想阅读所有的数据到内存来处理它,你不会知道多少内存来分配,直到你读文件。如果该文件的结构,这样的第一值的记录数,你可以做这样的事情:

 为size_t区域经济共同体= 0;
双*临时工= NULL;FILE *计划生育=的fopen(文件名,R);
如果(FP)
{
  如果(的fscanf(FP,%俎,&安培;区域经济共同体)== 1)
  {
    临时工=的malloc(sizeof的* *临时工RECs)的;
    如果(临时工)
    {
      //读取文件的内容到临时工
    }
  }
}

有时你需要分配的非常的大对象,像

  INT极大的相[1000] [1000] [1000]

假设一个4字节的整数,这个数组将需要4GB。不幸的是,堆栈帧(其中,本地变量被保持在大多数架构)往往比小得多,所以尝试分配该多存储器可能导致运行时错误(并且通常确实)。动态内存池(亦称堆)是典型的的不是堆栈较大,更谈不上任何一个堆栈帧。因此对于厌恶的东西你需要写类似

  INT(*极大的相)[1000] [1000] =的malloc(sizeof的*极大的相* 1000);

它仍然可能这样的请求失败;如果你的堆够fragemented,您可能没有一个连续的块大到足以喊得请求。如果有必要,你可以做零碎的分配;行不一定会在内存中相邻,但它更可能你就可以抓住所有你所需要的内存:

  INT ***极大的相=的malloc(sizeof的*极大的相* 1000);
如果(极大的相)
{
  用于(为size_t我= 0; I< 1000;我++)
  {
    极大的相[I] =的malloc(sizeof的*极大的相[I] * 1000);
    如果(极大的相[I])
    {
      极大的相[I] [J] =的malloc(sizeof的*极大的相[I] [J] * 1000);
      如果(极大的相[I] [J]。)
      {
        //初始化极大的相由[i] [j]的[K]
      }
    }
  }
}

最后,动态内存,您可以为您添加或删除数据,如列表,树,队列等你甚至可以建立自己的真正的字符串数据类型,它可以增长构建可扩展和收缩的容器当你追加到它的字符(类似于字符串键入C ++)。

Dynamic memory allocation is a very important topic in C programming. However, I've been unable to find a good explanation of what this enables us to do, or why it is required.

Can't we just declare variables and structs and never have to use malloc()?

As a side note, what is the difference between:

ptr_one = (int *)malloc(sizeof(int));

and

int *ptr_one = malloc(sizeof(int));

解决方案

You need to use dynamic memory when:

  • You cannot determine the maximum amount of memory to use at compile time;
  • You want to allocate a very large object;
  • You want to build data structures (containers) without a fixed upper size;

You don't always know how much memory you will need to set aside at compile time. Imagine processing a data file (a time series of temperatures, say), where the number of records in the file isn't fixed. You could have as few as 10 records or as many as 100000. If you want to read all that data into memory to process it, you won't know how much memory to allocate until you read the file. If the file is structured so that the very first value is the number of records, you could do something like this:

size_t recs = 0;
double *temps = NULL;

FILE *fp = fopen ( filename, "r" );
if ( fp )
{
  if ( fscanf( fp, "%zu", &recs ) == 1 )
  {
    temps = malloc( sizeof *temps * recs );
    if ( temps )
    {
      // read contents of file into temps
    }
  }
}

Sometimes you need to allocate a very large object, something like

int ginormous[1000][1000][1000];

Assuming a 4-byte integer, this array will require 4GB. Unfortunately, stack frames (where local variables are kept on most architectures) tend to be much smaller than that, so trying to allocate that much memory may lead to a run-time error (and typically does). The dynamic memory pool (a.k.a. the heap) is typically much larger than the stack, much less any one stack frame. so for something that obnoxious you'd need to write something like

int (*ginormous)[1000][1000] = malloc( sizeof *ginormous * 1000 );

It's still possible for a request like that to fail; if your heap is fragemented enough, you may not have a single contiguous block large enough to hande the request. If necessary, you could do a piecemeal allocation; rows won't necessarily be adjacent in memory, but it's more likely you'll be able to grab all the memory you need:

int ***ginormous = malloc( sizeof *ginormous * 1000 );
if ( ginormous )
{
  for ( size_t i = 0; i < 1000; i++ )
  {
    ginormous[i] = malloc( sizeof *ginormous[i] * 1000 );
    if ( ginormous[i] )
    {
      ginormous[i][j] = malloc ( sizeof *ginormous[i][j] * 1000 );
      if ( ginormous[i][j] )
      {
        // initialize ginormous[i][j][k]
      }
    }
  }
}

And finally, dynamic memory allows you to build containers that can grow and shrink as you add or remove data, such as lists, trees, queues, etc. You could even build your own real "string" data type that can grow as you append characters to it (similar to the string type in C++).

这篇关于为什么呢,或者,你需要在C动态分配内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆