Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
379 views
in Technique[技术] by (71.8m points)

malloc - Why, or when, do you need to dynamically allocate memory in 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));
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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++).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...