简体   繁体   English

我的C程序中的内存分配问题

[英]Memory allocation problem in my C program

If i'm writing a program in C that i suspect might take a lot of memory, can i use the malloc function. 如果我怀疑用C编写程序,可能会占用大量内存,可以使用malloc函数。 Does malloc know how much memory my program wants? malloc是否知道我的程序需要多少内存? I know it returns a value of the memory it found but how does it know if its enough? 我知道它会返回找到的内存的值,但是如何知道它是否足够?

Eg 例如

int * buffer;
buffer = (int*)malloc(sizeof(int)*70);

if(buffer==NULL){
    fprintf(stderr, "malloc error!");
}

Does malloc know how much memory my program wants? malloc是否知道我的程序需要多少内存?

You specify the amount of memory as malloc parameter, so that it knows how much memory to allocate 您可以将内存量指定为malloc参数,以便它知道要分配多少内存

In your example it will allocate sizeof(int)*70 bytes (on 32bit Windows 4*70=280 bytes, for example) 在您的示例中,它将分配sizeof(int)*70字节(例如,在32位Windows 4 * 70 = 280字节上)

I know it returns a value of the memory it found but how does it know if its enough? 我知道它会返回找到的内存的值,但是如何知道它是否足够?

It looks at your parameter and checks if OS has enough memory for you, if memory is not enough it returns NULL. 它查看您的参数并检查OS是否为您提供了足够的内存,如果内存不足,则返回NULL。

是的,如果没有足够的内存,则malloc返回NULL

malloc takes a parameter that defines the amount of memory required - and in your example it is enough memory to hold an array of 70 integers. malloc一个参数来定义所需的内存量-在您的示例中,该内存足以容纳70个整数的数组。

If it is unable to do so, it returns null . 如果无法这样做,则返回null

The parameter you give to malloc is the number of bytes you want for this particular piece of memory. 您为malloc提供的参数是此特定内存所需的字节数。

If you want a char array to store 4 chars, you have to do 如果要一个char数组存储4个char,则必须执行

char *tab;
tab = malloc(sizeof(*tab) * 4);

This will take the size of *tab which is a char, times 4, and allocate this space in memory. 这将使用*tab的大小(它是一个字符)乘以4,并在内存中分配此空间。
You have to know yourself how much is enough for your program to work. 您必须知道自己多少才可以运行程序。

You always have to tell malloc how much memory you require. 您总是必须告诉malloc您需要多少内存。 It never knows by itself. 它永远不会自己知道。

No, malloc does not know how much memory your program wants, you're the one who should know that, and you're telling malloc how much memory you need for that particular buffer. 不,malloc不知道您的程序需要多少内存,您是应该知道的人,并且您告诉malloc该特定缓冲区需要多少内存。

However, this buffer is not the total memory allocated to your program, only the memory allocated to this particular variable. 但是,此缓冲区不是分配给程序的总内存,而是分配给此特定变量的内存。 If there isn't enough memory in your system, malloc will return null. 如果系统中没有足够的内存,则malloc将返回null。

Bottom line, there's no way for you to tell the operating system that your program will need a lot of memory, you need to allocate the memory for each buffer you need and then check whether it returned NULL to see whether there's enough memory in the system. 最重要的是,您无法告诉操作系统您的程序将需要大量内存,您需要为所需的每个缓冲区分配内存,然后检查其是否返回NULL以查看系统中是否有足够的内存。 。

As others have said, you have to tell malloc how much memory you want. 正如其他人所说,您必须告诉malloc您想要多少内存。 Note that if you don't allocate enough memory initially, you can use realloc to request more memory. 请注意,如果最初没有分配足够的内存,则可以使用realloc请求更多的内存。

Here's an example. 这是一个例子。 Suppose you want to store a line of text (delimited by a newline) from an input stream, but you don't know how long the line is, so you don't know ahead of time how much memory to allocate. 假设您要存储输入流中的一行文本(由换行符分隔),但是您不知道该行有多长,因此您不提前知道要分配多少内存。 You can read the input stream piecemeal into a smaller fixed-size buffer, and append that to a dynamic buffer that you can resize as necessary: 您可以将输入流逐段读取到较小的固定大小的缓冲区中,并将其附加到可以根据需要调整大小的动态缓冲区中:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

/**
 * Reads a line of text (delimited by a newline character) from an 
 * input stream into a dynamic buffer. 
 */
char *getNextLine(FILE *stream, size_t *lineSize)
{
  char inbuf[SIZE];  // fixed-size input buffer
  char *line = NULL; // points to our dynamic buffer
  char *newline = NULL;
  char *(*append)(char *, const char *) = strcpy;

  *lineSize = 0;

  /**
   * Read from the input stream until we see a newline character
   * or the read fails (EOF or error).
   */
  while (!newline && fgets(inbuf, sizeof inbuf, stream))
  {
    /**
     * Resize the buffer to accomodate the string in the input buffer
     * (allocates the buffer the first time through).
     */
    char *tmp = realloc(line, *lineSize + strlen(inbuf) + 1);
    if (tmp)
    {
      /**
       * Check for a newline in the input buffer
       */
      newline = strchr(inbuf, '\n');

      /**
       * If present, overwrite the newline with a 0 (nul terminator
       * character).  If you want to keep the newline in the target
       * buffer, skip this step.
       */
      if (newline)
        *newline = 0;

      /**
       * Assign the temporary variable back to line and update the 
       * output buffer size.
       */
      line = tmp;
      *lineSize += strlen(inbuf) + 1;

      /**
       * Write the contents of the input buffer to the target buffer.
       * First time through the loop we'll use strcpy (called through
       * the append function pointer); on each successive iteration
       * we'll use strcat to append the contents of the input buffer
       * to the target buffer.
       */
      append(line, inbuf);
      append = strcat;
    }
    else
    {
      /**
       * The realloc function failed; at this point, we'll just return
       * what we have.
       */
      printf("Unable to extend buffer\n");
    }
  }

  if (!newline && !feof(stream))
  {
    printf("Error on read!\n");
  }

  return line;
}

This code uses realloc instead of malloc for the initial allocation (calling realloc with NULL as the first argument is the same as calling malloc ). 这段代码使用realloc代替malloc进行初始分配(调用NULL作为第一个参数的realloc与调用malloc相同)。

Note that we assign the result of realloc to a temporary variable. 请注意,我们将realloc的结果分配给一个临时变量。 If realloc fails (there isn't enough memory to satisfy the request) it will return NULL; 如果realloc失败(没有足够的内存来满足请求),它将返回NULL;否则,它将返回NULL。 if we assigned this to line we'd lose our pointer to any memory we've already allocated, causing a memory leak. 如果将其分配给line则会丢失指向已经分配的任何内存的指针,从而导致内存泄漏。

There's a little trickery with the append function pointer. append函数指针有些麻烦。 The first time through the loop we want to copy our input buffer to the target buffer, so we set append to point to strcpy . 第一次通过循环,我们要将输入缓冲区复制到目标缓冲区,因此我们将append设置为指向strcpy After that, we want to append what's in the input buffer to the contents of the target buffer, so we set append to point to strcat . 之后,我们想将输入缓冲区中的内容append到目标缓冲区的内容中,因此我们将append设置为指向strcat

Note that it's up to the caller to free the dynamic buffer when it's done with it. 请注意,在完成动态缓冲区处理后,调用方将有权释放它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM