50%规则
我正在编写一个程序来测试动态内存分配,以了解 50% 规则的适用情况。
该程序有 10,000 个指向动态分配的内存块的指针。它还有一个数组来存储每个块的大小。它应该:
- 使用
malloc()
为ptrList
的每个元素动态分配一块内存。这些块的大小应在 1 到 10,000 字节的范围内随机选择,并且块大小应存储在sizeList
数组中。 - 初始块分配后,程序应重复释放块并分配新块。这应该循环 100,000 次迭代。在每次迭代中,
ptrList
中的索引被随机选择,该块被释放,然后替换为具有随机大小的新的动态分配的块。 - 每 100 次迭代后,它应该打印出一行,显示迭代计数、近似堆大小(由任何块中包含的最高和最低内存地址之间的差异确定)以及指向的所有块的总大小通过
ptrList
。
我的程序编码如下:
#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;
}
我是否以正确的方式处理内存的分配/释放?在我使用 int j
实现 for
循环之前,我的程序已编译并运行(无输出)。它在我实现后挂起,所以也许有人可以帮助我解决那里的问题。
编辑: 50% 规则是所有块的总大小除以堆大小的近似值,通常约为 50%。
I am writing a program that tests dynamic memory allocation to see how well the 50-percent rule holds.
The program has 10,000 pointers to dynamically allocated blocks of memory. It also has an array to store the size of each block. It should:
- Use
malloc()
to dynamically allocated a block of memory for every element ofptrList
. These blocks should have sizes that are selected randomly in the range of 1 to 10,000 bytes and the block size should be stored in thesizeList
array. - After initial block allocation, the program should repeatedly free blocks and allocate new ones. This should loop for 100,000 iterations. On each iteration, an index in
ptrList
is chosen at random, the block is freed, and then replaced with a new dynamically allocated block with random size. - After every 100 iterations, it should print out a line that shows the iteration count, the approximate heap size (determined by the difference between the highest and lowest memory addresses contained in any of the blocks), and the total size of all blocks pointed to by
ptrList
.
I have my program coded like so:
#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;
}
Am I approaching the allocation/deallocation of memory the right way? My program compiles and runs (without output) before I implemented the for
loop with int j
. It hangs after I implemented it, so perhaps someone can help me pin the problem there as well.
Edit: The 50-percent rule is the total size of all blocks divided by the approximation of the heap size will generally be around 50 percent.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
除了繁琐的代码(极其不必要的代码)之外,您还遇到了变量和循环的一些问题:您的 for (int i = 0; i < TEST_LENGTH; i++)... 循环,它实现了步骤 2规范是一个循环,在该循环中,每 100 步您应该打印当前统计信息。拥有外部
for (int j = 0; j < 1000; j++)
循环并测试j%100
余数是无意义的。要调试此类问题,请将 BLOCK_COUNT、TEST_LENGTH、SIZE_LIMIT 中的每个大数字去掉两个或三个零,将
j
循环限制更改为 10,然后添加printf("j= ..." ...)
在for (int j ...) {
之后,这样您就可以知道发生了什么。通过这些更改,您将看到:然后可以得出结论,您的程序似乎挂起,因为它正在慢慢地将 j 计数到 100,以达到
j%100 == 0
。现在我将提到两个需要删除的小问题,然后将提到您的程序的一个主要问题。
而不是
写
(或者可能是 MAX_INT 的变体)和(如果您需要
j
和/或remainder
,但您不需要)而不是写
一个主要问题对于您的程序:当您在第 2 部分中说
free(ptrList[index]);
时,您可能会释放占用当前最小或最大内存地址的项目。解决这个问题的一种方法是维护具有最小/最大值和先进先出规则的优先级队列;我认为你会发现更简单的是在分配时不跟踪最小值/最大值,而是在每次打印输出之前有一个循环来查找最小值/最大值。您的程序存在一个小问题:对于某些索引,使用的最大地址不是
ptrList[index]
,而是ptrList[index]+sizeList[index]
。Besides cruft (egregiously unnecessary code) you've got some problems with variables and loops: Your
for (int i = 0; i < TEST_LENGTH; i++)...
loop, which implements step 2 of the spec, is the loop within which, every 100 steps, you should print current stats. Having an outerfor (int j = 0; j < 1000; j++)
loop and testingj%100
remainders is nonsense.For debugging a problem like that, knock two or three zeroes off each of the big numbers BLOCK_COUNT, TEST_LENGTH, SIZE_LIMIT, change the
j
loop limit to 10, and add aprintf("j=..." ...)
afterfor (int j ...) {
so you can tell what's happening. With such changes, you will see:and then can conclude that your program seemed to hang because it was slowly counting j up to 100 to get to
j%100 == 0
.Now I'll mention two minor cruft items to remove, and after that will mention a major problem with your program.
Instead of
write
(or possibly a variant of MAX_INT) and (if you needed
j
and/orremainder
, which you don't) instead ofyou would write
A major problem with your program: When you say
free(ptrList[index]);
in part 2, you might be freeing the item that accounted for the current minimum or maximum memory addresses. One way to solve this problem is maintain priority queues with min/max values and fifo discipline too; what you will find simpler, I think, is to not track min/max while allocating, but instead just have a loop to find min/max right before each printout.A minor problem with your program: The maximum address used is not
ptrList[index]
for some index, butptrList[index]+sizeList[index]
.