50%规则

时间:2011-11-08 01:44:03

标签: c malloc free

我正在编写一个测试动态内存分配的程序,以查看50%规则的保持程度。

该程序有10,000个动态分配内存块的指针。它还有一个数组来存储每个块的大小。它应该:

  1. 使用malloc()ptrList的每个元素动态分配一块内存。这些块的大小应在1到10,000字节范围内随机选择,块大小应存储在sizeList数组中。
  2. 在初始块分配之后,程序应重复释放块并分配新块。这应循环100,000次迭代。在每次迭代中,随机选择ptrList中的索引,释放该块,然后用随机大小的新动态分配块替换。
  3. 每100次迭代后,它应打印出一行显示迭代次数,近似堆大小(由任何块中包含的最高和最低内存地址之间的差异确定)以及所有块的总大小ptrList指向的块。
  4. 我的程序编码如下:

    #include <stdio.h>
    #include <pthread.h>   /* for pthreads */
    #include <stdlib.h>    /* for exit */
    
    /** Number of memory blocks to allocate/deallocate. */
    #define BLOCK_COUNT 10000
    
    /** Number of free/malloc operations to perform */
    #define TEST_LENGTH 100000
    
    /** Maximum size of an allocated block. */
    #define SIZE_LIMIT 10000
    
    int main( int argc, char *argv[] ) {
      // Array of pointers to all blocks that have been allocated.
      char *ptrList[ BLOCK_COUNT ];
    
      // Array of sizes for each block, so we can know how much memory we're using.
      int sizeList[ BLOCK_COUNT ];
    
      // Insert your code here
      for (int j = 0; j < 1000; j++) {
    
          int minimum = 0;
          int maximum = 0;
          int total = 0, remainder = 0;
    
          for (int i = 0; i < BLOCK_COUNT; i++) {
              int size = (rand() % SIZE_LIMIT) + 1;
              ptrList[i] = malloc (size);
              sizeList[i] = size;
              total += size;
              int heapsize = (int)ptrList[i];
    
              if (i == 0) {
                  maximum = heapsize;
                  minimum = heapsize;
              }
              else {
                  if (heapsize > maximum) {
                      maximum = heapsize;
                  }
                  if (heapsize < minimum) {
                      minimum = heapsize;
                  }
              }
          }
    
          for (int i = 0; i < TEST_LENGTH; i++) {
              int index = rand() % BLOCK_COUNT;
              int size = (rand() % SIZE_LIMIT) + 1;
              free(ptrList[index]);
              total -= sizeList[index];
              ptrList[index] = malloc (size);
              sizeList[index] = size;
              total += sizeList[index];
              int heapsize = (int)ptrList[index];
    
              if (heapsize > maximum) {
                  maximum = heapsize;
              }
              if (heapsize < minimum) {
                  minimum = heapsize;
              }
          }
    
          if (j > 0) {
              remainder = j % 100;
          }
    
          if (remainder == 0 ) {
              //printf("%d", example);
              printf("%d %d %d\n", j, maximum - minimum, total);
          }
    
          for (int i = 0; i < BLOCK_COUNT; i++) {
              free(ptrList[i]);
          }
    
      }
    
      return 0;
    }
    

    我是否以正确的方式接近内存的分配/释放?在我用for实现int j循环之前,我的程序编译并运行(没有输出)。它在我实现之后就会挂起,所以也许有人可以帮我解决问题。

    编辑: 50%规则是所有块的总大小除以堆大小的近似值通常约为50%。

1 个答案:

答案 0 :(得分:4)

除了cruft(极其不必要的代码)之外,你还遇到了变量和循环的一些问题:实现规范第2步的for (int i = 0; i < TEST_LENGTH; i++)...循环是一个循环,在这个循环中,每100个步骤,你应该打印目前的统计数据。拥有外部for (int j = 0; j < 1000; j++)循环并测试j%100剩余部分是无稽之谈。

为了调试这样的问题,从每个大数字BLOCK_COUNT,TEST_LENGTH,SIZE_LIMIT中敲掉两个或三个零,将j循环限制更改为10,并在{{printf("j=..." ...)之后添加for (int j ...) { 1}}这样你就可以知道发生了什么。通过这些更改,您将看到:

  j=0 0 0
  0 556736 507760
  j=1 0 0
  j=2 0 0
  j=3 0 0
  ...

然后可以得出结论,你的程序似乎挂了,因为它慢慢计数j到100来j%100 == 0

现在我要提到要移除的两个小件物品,之后会提到你的程序存在的主要问题。

而不是

  int minimum = 0;
  int maximum = 0;
  ...
     if (i == 0) {
        maximum = heapsize;
        minimum = heapsize;
     }
     else {
       if (heapsize > maximum) {
          maximum = heapsize;
     }
     if (heapsize < minimum) {
          minimum = heapsize;
     }

  int minimum = MAX_INT;
  int maximum = 0;
  ...
     if (heapsize > maximum)
        maximum = heapsize;
     if (heapsize < minimum)
        minimum = heapsize;

(或者可能是MAX_INT的变体)和(如果你需要j和/或remainder,你不需要)而不是

  if (j > 0) {
      remainder = j % 100;
  }

  if (remainder == 0 ) {
     ...
你会写

  if (j>0 && j%100 == 0 ) {
     ...

程序的一个主要问题:当您在第2部分中说free(ptrList[index]);时,您可能正在释放占当前最小或最大内存地址的项目。解决此问题的一种方法是维护具有最小/最大值和fifo规则的优先级队列;我认为,你会发现更简单的是在分配时不跟踪最小值/最大值,而是在每次打印输出之前只有一个循环来找到最小值/最大值。

您的计划遇到的一个小问题:某些索引使用的最大地址不是ptrList[index],而是ptrList[index]+sizeList[index]