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

时间:2012-02-07 13:33:07

标签: c

如果我在C中编写一个我怀疑会占用大量内存的程序,我可以使用malloc函数吗? malloc知道我的程序需要多少内存吗?我知道它返回了它找到的内存值,但它是如何知道它是否足够?

E.g

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

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

7 个答案:

答案 0 :(得分:2)

  

malloc知道我的程序需要多少内存吗?

您将内存量指定为malloc参数,以便它知道要分配多少内存

在您的示例中,它将分配sizeof(int)*70个字节(例如32位Windows 4 * 70 = 280个字节)

  

我知道它会返回它找到的内存值,但它是如何知道它是否足够?

查看你的参数并检查操作系统是否有足够的内存,如果内存不足则返回NULL。

答案 1 :(得分:1)

是的,如果内存不足,malloc会返回NULL

答案 2 :(得分:1)

malloc接受一个定义所需内存量的参数 - 在您的示例中,它足以容纳70个整数的数组。

如果无法执行此操作,则会返回null

答案 3 :(得分:1)

您为malloc提供的参数是您对此特定内存所需的字节数。

如果你想要一个char数组来存储4个字符,你必须这样做

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

这将使*tab的大小为char,乘以4,并在内存中分配此空间。
您必须了解自己的程序能够运作多少

答案 4 :(得分:0)

你总是要告诉malloc你需要多少内存。它永远不会知道。

答案 5 :(得分:0)

不,malloc不知道你的程序需要多少内存,你应该知道那个,而且你告诉malloc你需要多少特定缓冲区的内存。

但是,此缓冲区不是分配给程序的总内存,而是分配给此特定变量的内存。如果系统中没有足够的内存,malloc将返回null。

最重要的是,您无法告诉操作系统您的程序需要大量内存,您需要为每个需要的缓冲区分配内存,然后检查它是否返回NULL以查看是否有足够的内存在系统中。

答案 6 :(得分:0)

正如其他人所说,你必须告诉malloc你想要多少记忆。请注意,如果最初没有分配足够的内存,可以使用realloc来请求更多内存。

这是一个例子。假设您想要从输入流存储一行文本(由换行符分隔),但您不知道该行的长度,因此您不能提前知道要分配多少内存。您可以将输入流逐个读取到较小的固定大小的缓冲区中,并将其附加到动态缓冲区,您可以根据需要调整大小:

#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;
}

此代码使用realloc而不是malloc进行初始分配(使用NULL调用realloc,因为第一个参数与调用malloc相同)。

请注意,我们将realloc的结果分配给临时变量。如果realloc失败(没有足够的内存来满足请求),它将返回NULL;如果我们将它分配给line,我们将丢失指向我们已经分配的任何内存的指针,从而导致内存泄漏。

append函数指针有点诡计。第一次通过循环我们想要将输入缓冲区复制到目标缓冲区,因此我们将append设置为指向strcpy。之后,我们想要将输入缓冲区中的内容附加到目标缓冲区的内容中,因此我们将append设置为指向strcat

请注意,调用者可以在动态缓冲区完成后释放动态缓冲区。