我正在编写一个测试动态内存分配的程序,以查看50%规则的保持程度。
该程序有10,000个动态分配内存块的指针。它还有一个数组来存储每个块的大小。它应该:
malloc()
为ptrList
的每个元素动态分配一块内存。这些块的大小应在1到10,000字节范围内随机选择,块大小应存储在sizeList
数组中。ptrList
中的索引,释放该块,然后用随机大小的新动态分配块替换。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;
}
我是否以正确的方式接近内存的分配/释放?在我用for
实现int j
循环之前,我的程序编译并运行(没有输出)。它在我实现之后就会挂起,所以也许有人可以帮我解决问题。
编辑: 50%规则是所有块的总大小除以堆大小的近似值通常约为50%。
答案 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]
。