C:内存管理

C:内存管理,c,memory-management,conditional,dynamic-memory-allocation,C,Memory Management,Conditional,Dynamic Memory Allocation,如何根据这些条件释放内存:如果使用的内存小于系统容量的25%,则释放50%的未使用内存 请参阅:dlist类中的FreeMemoryCondition方法 问题: 如何检查数据列表的大小(包括已使用或未使用的内存插槽) 如何检查dlist节点是否有已占用的内存插槽 以下是我的代码尝试: #define TRUE 1 #define FALSE 0 typedef struct s_elem elem; struct s_elem { int value; elem *next

如何根据这些条件释放内存:如果使用的内存小于系统容量的25%,则释放50%的未使用内存

请参阅:dlist类中的FreeMemoryCondition方法

问题:

如何检查数据列表的大小(包括已使用或未使用的内存插槽)

如何检查dlist节点是否有已占用的内存插槽

以下是我的代码尝试:

#define TRUE 1
#define FALSE 0

typedef struct s_elem elem;

struct s_elem {
    int value;
    elem *next;
    elem *prev;
};

typedef struct {
    elem *topL;
    elem *topR;
    elem *head;
    elem *tail;
    int size;
} dlist;

void dl_initialise(dlist *dl);
void dl_initialise_block(dlist *dl, int num_elems);
void dl_push(dlist *dl, int value, int is_left_stack);
int dl_pop(dlist *dl, int is_left_stack);
void dl_print(dlist *dl);
void dl_freeMemory(dlist *dl); //edited
void dl_freeMemoryConditional(dlist *dl); //edited
数据列表

/*
dlist:一种动态数据结构,它实现了int值的双链接列表,并允许在其左侧或右侧以类似堆栈的方式进行填充。
功能push和pop可用,push可确保左侧和右侧堆栈不会碰撞。
它还将列表的第一个元素保留在堆栈的左侧,最后一个元素保留在堆栈的右侧。
数据列表通常初始化为两个元素:头部和尾部。
--此实现不是线程安全的--
*/
#包括
#包括
#包括“dlist.h”
//初始化数据列表,创建首尾元素
无效dl_初始化(数据列表*dl){
dl->head=malloc(sizeof(elem));
dl->head->prev=NULL;
dl->tail=malloc(sizeof(elem));
dl->head->next=dl->tail;
dl->tail->prev=dl->head;
dl->tail->next=NULL;
dl->head->value=-1;
dl->tail->value=-1;
dl->topL=NULL;
dl->topR=NULL;
dl->size=2;
}
//初始化新块,增加数据列表中的可用空间
无效数据初始化块(数据列表*dl,整数元素){
如果(元素数<1)
返回;
元素*电流;
如果(dl->topL)
当前=dl->topL;
其他的
电流=dl->head;
int i=元素数;
而(i-->0){
当前->下一步=malloc(sizeof(elem));
当前->下一个->上一个=当前;
当前=当前->下一步;
当前->值=-1;
}
如果(dl->topR){
当前->下一步=dl->topR;
dl->topR->prev=当前;
}否则{
当前->下一步=dl->尾部;
dl->tail->prev=当前;
}
dl->size+=num_元素;
}
//堆栈中的推送操作-考虑侧面
void dl_push(dlist*dl,int值,int为左栈){
如果(是左堆栈){
如果(dl->topL!=NULL&&(dl->topL->next==dl->topR|dl->topL->next==dl->tail))
dl_初始化_块(dl,dl->大小);
如果(dl->topL)
dl->topL=dl->topL->next;
其他的
dl->topL=dl->head;
dl->topL->value=value;
}否则{
如果(dl->topR!=NULL&&(dl->topR->prev==dl->topL|dl->topR->prev==dl->head))
dl_初始化_块(dl,dl->大小);
如果(dl->topR)
dl->topR=dl->topR->prev;
其他的
dl->topR=dl->tail;
dl->topR->value=value;
}
}
//在堆栈中的pop操作-考虑到侧面
int dl_pop(dlist*dl,int是左栈){
国际关系;
如果(是左堆栈(&dl->topL){
res=dl->topL->value;
dl->topL->value=-1;
dl->topL=dl->topL->prev;
}否则如果(!是左堆栈(&dl->topR){
res=dl->topR->value;
dl->topR->value=-1;
dl->topR=dl->topR->next;
}
返回res;
}
//释放数据列表占用的内存
void dl_freemory(dlist*dl){
元素*电流=dl->head;
elem*下一步;
while(当前!=NULL){
下一步=当前->下一步;
自由(电流);
当前=下一个;
}
}
//条件内存释放
void dl_freemoryconditional(dlist*dl){
元素*电流=dl->head;
elem*下一步;
//元素*温度;
int size=dl->size;
int容量=0;
//检查容量
while(当前=!NULL){
下一步=当前->下一步;
容量++;
当前=下一个;
}
电流=dl->head;
//如果是下一步,请释放50%的内存;
如果(rand()%2>0){
自由(电流);
//}否则{
//温度=电流;
}
当前=下一个;
}
}
}
//打印数据列表的全部内容
无效dl_打印(数据列表*dl){
元素*电流=dl->head;
printf(“数据列表内容:\n”);
//评论
while(当前!=NULL){
printf(“%d”,当前->值);
当前=当前->下一步;
}
printf(“\n”);
}
主要

#包括
#包括
#包括
#包括“dlist.h”
dlist dl;//程序中使用的主结构
//辅助线程函数
void*do_work(void*p_isL){
int isL=*((int*)p_isL);
int电流=0;
而(电流<50){
pthread_mutex_t count_mutex;
pthread_mutex_lock(&count_mutex);
如果(rand()%2>0){
dl_推送(&dl,rand()%100,isL);
//dl_打印(&dl);
电流++;
}否则{
dl_pop(&dl,rand()%100);
电流++;
}
pthread_mutex_unlock(&count_mutex);
}
返回NULL;
}
//主要功能
int main(int argc,char*argv[]){
pthread_mutex_t count_mutex;
pthread_mutex_init(&count_mutex,NULL);
//参数表示最小(和初始)数据列表大小
int最小_size=atoi(argv[1]);
//数据列表初始设置
dl_初始化(&dl);
//分配初始块
dl_initialise_块(&dl,最小大小为-2);//初始化后,数据列表始终包含2项
//工作线程初始化
pthread_t线程[2];
int-tL=1;
int tR=0;
pthread_create(&threads[0],NULL,do_work,(void*)&tL);
pthread_create(&threads[1],NULL,do_work,(void*)&tR);
//工作线程与主线程的同步
pthread_join(线程[0],NULL);
pthread_join(线程[1],NULL);
//测试结束数据
dl_print(&dl);//输出数据列表的状态
dl_freemoryconditional(&dl);//释放数据列表占用的内存
返回0;
}

您不应该假设使用了多少内存,即使是操作系统报告的数字,由于文件系统缓存占用,通常也会有相当大的损失
/*
    dlist: a dynamic data structure that implements a doubly linked list of int values and allows being filled in a stack-like fashion both at its left or right sides.
    functions push and pop are available, and push ensures that the left and righ hand side stacks do not collide. 
    It also reserves the first element of the list to the left hand side stack, and the final element to the right hand side of the stack.
    dlist is normally initialised to 2 elements: the head and the tail.
    -- This implementation is not thread safe. --
*/

#include <stdlib.h>
#include <stdio.h>
#include "dlist.h"

// initialises a dlist, creating the elements head and tail
void dl_initialise(dlist *dl) {
    dl->head = malloc(sizeof(elem));
    dl->head->prev = NULL;
    dl->tail = malloc(sizeof(elem));
    dl->head->next = dl->tail;
    dl->tail->prev = dl->head;
    dl->tail->next = NULL;
    dl->head->value = -1;
    dl->tail->value = -1;
    dl->topL = NULL;
    dl->topR = NULL;
    dl->size = 2;
}

// initialises a new block, increasing the available space in a dlist
void dl_initialise_block(dlist *dl, int num_elems) {

    if(num_elems < 1)
        return;

    elem *current;
    if(dl->topL)
        current = dl->topL;
    else
        current = dl->head;
    int i = num_elems;
    while(i-- > 0) {
        current->next = malloc(sizeof(elem));
        current->next->prev = current;
        current = current->next;
        current->value = -1;
    }
    if(dl->topR) {
        current->next = dl->topR;
        dl->topR->prev = current;
    } else {
        current->next = dl->tail;
        dl->tail->prev = current;
    }
    dl->size += num_elems;
}

// push operation as in a stack - takes into account the side
void dl_push(dlist *dl, int value, int is_left_stack) {
    if(is_left_stack) {
        if(dl->topL != NULL && (dl->topL->next == dl->topR || dl->topL->next == dl->tail))
            dl_initialise_block(dl, dl->size);
        if(dl->topL)
            dl->topL = dl->topL->next;
        else
            dl->topL = dl->head;
        dl->topL->value = value;
    } else {
        if(dl->topR != NULL && (dl->topR->prev == dl->topL || dl->topR->prev == dl->head))
            dl_initialise_block(dl, dl->size);
        if(dl->topR)
            dl->topR = dl->topR->prev;
        else
            dl->topR = dl->tail;
        dl->topR->value = value;
    }
}

// pop operation as in a stack - takes into account the side
int dl_pop(dlist *dl, int is_left_stack) {
    int res;
    if(is_left_stack && dl->topL) {
        res = dl->topL->value;
        dl->topL->value = -1;
        dl->topL = dl->topL->prev;
    } else if(!is_left_stack && dl->topR) {
        res = dl->topR->value;
        dl->topR->value = -1;
        dl->topR = dl->topR->next;
    }
    return res;
}

// free up the memory occupied by a dlist
void dl_freeMemory(dlist *dl) {

    elem *current = dl->head;
    elem *next;

    while(current != NULL) {
    next = current->next;
    free(current);
    current = next;
    }
}

// conditional memory free-up
void dl_freeMemoryConditional(dlist *dl) {

    elem *current = dl->head;
    elem *next;
    //elem *temp;
    int size = dl->size;
    int capacity = 0;

    //check capacity
    while(current = !NULL) {
        next = current->next;
        capacity++;
        current = next;
    }

    current = dl->head; 

    //free 50% of memory if <25% is in use
    if(size < (capacity/4)){
        //temp = current;
        while(current = !NULL) {
            next = current->next;
            if(rand() % 2 > 0) {
                free(current);
            //} else {
                //temp = current;
            }
        current = next;
        }
    }
}

// print the full contents of a dlist
void dl_print(dlist *dl) {
    elem *current = dl->head;
    printf("DList contents:\n");
    // comment

    while(current != NULL) {
        printf("%d ", current->value);
        current = current->next;
    }
    printf("\n");
}
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include "dlist.h"

dlist dl; // main structure used in the program

// worker thread function
void* do_work(void *p_isL) {
    int isL = *((int *)p_isL);
    int current = 0;

    while (current < 50) {

        pthread_mutex_t count_mutex;

        pthread_mutex_lock(&count_mutex);

        if(rand() % 2 > 0) {
            dl_push(&dl, rand() % 100, isL);
            //dl_print(&dl);
            current++;
        } else {
            dl_pop(&dl, rand() % 100);
            current++;
        }
    pthread_mutex_unlock(&count_mutex);
    }
    return NULL;
}

// main function
int main(int argc, char *argv[]) {

    pthread_mutex_t count_mutex;
    pthread_mutex_init(&count_mutex, NULL);

    // parameter indicates minimum (and initial) dlist size
    int minimum_size = atoi(argv[1]);

    // dlist initial setup
    dl_initialise(&dl);

    // allocate initial block
    dl_initialise_block(&dl, minimum_size - 2); // dlists always contain 2 items after initialisation

    // worker thread initialisation
    pthread_t threads[2];
    int tL = 1;
    int tR = 0;
    pthread_create(&threads[0], NULL, do_work, (void *)&tL);
    pthread_create(&threads[1], NULL, do_work, (void *)&tR);

    // synchronisation of worker threads with the main one
    pthread_join(threads[0], NULL);
    pthread_join(threads[1], NULL);

    // END OF TEST DATA

    dl_print(&dl); // output the state of the dlist

    dl_freeMemoryConditional(&dl); // free the memory occupied by the dlist

    return 0;
}