【问题标题】:Contiguious dynamic memory allocation in linked list链表中的连续动态内存分配
【发布时间】:2014-09-29 12:28:59
【问题描述】:
#include <stdio.h>
#include <malloc.h>
#include <conio.h>

typedef struct node
{
    int info;
    struct node* next;
} node;

node* fi = NULL, *la = NULL, *ptr;

void insertfi()
{
    ptr = (node*)malloc(sizeof(node));
    printf("\nEnter info\n");
    scanf("%d", &ptr->info);
    ptr->next = fi;
    if (fi == NULL && la == NULL)
    {
        fi = la = ptr;
    }
    else
    {
        fi = ptr;
    }
}

void print()
{
    ptr = fi;
    while (ptr != NULL)
    {
        printf("|%d|-->", ptr->info);
        ptr = ptr->next;
    }
}

int main()
{
    int i, ch;
    do
    {
        printf("\nEnter your choice \n1.insert node\n2.view node\n3.exit\n");
        scanf("%d", &ch);
        if (ch == 1)
        {
            insertfi();
        }
        else if (ch == 2)
        {
            print();
        }
        else
            printf("Exiting\n");
    } while (ch != 3);
    return 0;
}

我想在我正在处理的程序中节省空间。该程序通过将节点的地址存储在结构中的下一个指针中来创建节点并连接它们。 我想要一些不使用 *next 指针转到下一个节点的方法 - 如果这样做,我将能够节省 2 个字节的内存。

我一直在思考是否有一种方法可以在动态内存分配中连续分配地址,以便我将第一个节点的地址存储在指针中,然后在修改地址后遍历或做任何事情。

地址是如何工作的——我的意思是如何通过在指针中输入地址来访问它们 然后打印出来?

这是一个示例程序:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main ()
{
    int a[10],i,*ptr;
    for(i=0;i<10;i++)
    {
        a[i]=rand()%15;
    }
    for(i=0;i<10;i++)
    {
        printf("%6x\n",&a[i]);
    }
    ptr=&a[0];
    printf("\n\n\n%d\n",*ptr);

}

它以连续的方式打印地址,但我不知道如何手动分配它们,例如 ptr=0022ff04 然后使用 `printf("%d",*ptr);


#include<conio.h>

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<stdbool.h>

#define max 20

typedef struct node
{
    int info;
    int row;
    int colum;
    struct node *next;
}node;

node *ptr,*fi=NULL,*la=NULL;

int r,c,i,j,sparse[max][max],decompmatx[max][max];

void makenode(int getrow,int getcolum,int getinfo)

{
ptr=(node*)malloc(sizeof(node));
ptr->next=NULL;
if(fi==NULL)
{
    ptr->info=getinfo;
    ptr->row=getrow;
    ptr->colum=getcolum;
    fi=la=ptr;  
}
else
{
    la->next=ptr;
    la=ptr;
    ptr->info=getinfo;
    ptr->row=getrow;
    ptr->colum=getcolum;
}

}

void decompress()

{
int temp;
temp=0;
ptr=fi;
while(ptr!=NULL)
{
    decompmatx[ptr->row][ptr->colum]=ptr->info;
    ptr=ptr->next;
}
for(i=0;i<=r-1;i++)
    {
        for (j=0;j<=c-1;j++)
        {
            if(decompmatx[i][j]>0)
            {

            }
            else
            decompmatx[i][j]=0;
        }
    }
printf("\nValue decompressed\n");
for(i=0;i<r;i++)
{
    for(j=0;j<c;j++)
    printf("%d  ",decompmatx[i][j]);
    if((temp%c)==0)
    printf("\n");
    else
    temp++;

}

}

void showsparse()

{
int temp;
temp=0;
for(i=0;i<r;i++)
{
    for(j=0;j<c;j++)
    printf("%d  ",sparse[i][j]);
    if((temp%c)==0)
    printf("\n");
    else
    temp++;

}

}

void print()

{
ptr=fi;
while(ptr!=NULL)
{
    printf("|%d|%d||%d|--->",ptr->info,ptr->row,ptr->colum);
    ptr=ptr->next;
}   


}

int main()

{
int ch;
do
{
printf("\nInput choice\n1.Make Sparse Matrix\n2.compress Matrix\n3.Decompress 
Matrix\n4.Exit...");
scanf("%d",&ch);
if(ch==1)
{
    printf("Input the rows\n");
    scanf("%d",&r);
    printf("Enter colum\n");
    scanf("%d",&c);
    printf("Printing the %dx%d matrix\n",r,c);
    for(i=0;i<=r-1;i++)
    {
        for (j=0;j<=c-1;j++)
        {
            sparse[i][j]=rand()%2;
        }
    }
    showsparse();
    printf("\nTotal Byte comsuming is =%d\n",r*c*2);
}
else if(ch==2)
{
    for(i=0;i<=r-1;i++)
    {
        for (j=0;j<=c-1;j++)
        {
            if(sparse[i][j]!=0)
            {
                makenode(i,j,sparse[i][j]);
            }

        }
    }
    printf("Data compressed\n");
    print();
    printf("size of node =%d",sizeof(node));

}
else if(ch==3)
{
    decompress();   
}

else
{
    printf("\nExiting..............\n");
}
}while(ch!=4);

getch();


}

【问题讨论】:

  • 您无法专门为malloc 设置地址。例如,您可以建议操作系统为您提供一些空间,从您选择的地址开始,例如 mmap,但它永远不受您的控制,因为您想要的地址可能属于其他人(操作系统,另一个过程等)放在首位。
  • 您可以分配一个指针数组(因此,类型为node **),注意根据需要调整数组的大小
  • 我想在我的程序中存储多个整数,所以我需要一个结构,应该有某种方式,因为我的前辈已经做到了.....
  • 创建一个非常大的静态 int 数组,可能使用 malloc 或定义一个。大到可以装下所有东西。您是否担心位置或 numa 问题?非常大的数据块并不能很好地放入 cpu 缓存中,因此您需要全面了解系统的缓存架构。第一的。然后担心第二个写代码。
  • 实际上我想通过以二进制形式打开二维数组中的图像然后将非空位置存储在链表中(如果图像像 0 1 0 1 0 1 0 1)来制作图像压缩程序0 0 0 0 1 1 0 1 0 0 1 1 那么我只会将那些存储在结构中定义的 1 位整数中......如果我使用这种方法,元素将是行列和 1 个整数图像压缩率将是更高......

标签: c memory dynamic allocation contiguous


【解决方案1】:

以下内容已由 cmets 中的 jim mcnamara 和 japreiss 提出。

使用预分配对象池代替动态分配。例如:

node my_pool = malloc(10000 * sizeof(pool));

然后用数组索引替换指针:

typedef struct node
{
    int info;
    int next_index;
} node;

因此,您现在可以使用数组索引,而不是使用指针。为什么这么好?

  • 您可以确保您的对象分配在连续的内存中(这可以提高缓存局部性并最终提高性能)
  • 您可以减小对象的大小,例如使用uint16_t 作为您的索引(如果您使用的是 64 位平台,即使 uint32_t 也会有所改进)
  • 如果malloc 存储管理/调试数据浪费了内存,你会改进它
  • 在数组中分配数据比使用malloc 更快
  • 如果您不关心何时释放,您可以一次释放所有对象:free(my_pool)

当然,没有什么是无条件的好。使用池有缺点(例如,它会浪费可用于其他目的的内存)。

【讨论】:

  • 缺点是这种方法的全部问题我想为我的图像压缩程序使用有限的内存我已经在上面的帖子中评论了我的图像处理程序我将使用按位运算符我将发布一个原型该计划的看看你们将能够提供有关该计划的更多帮助......
  • 在这种情况下,空间复杂度是主要动机,时间可以增加,但考虑到当今的 cpu,在压缩图像时它会非常少.....
猜你喜欢
  • 2011-01-15
  • 2020-12-08
  • 2019-10-14
  • 2021-02-09
  • 2013-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-20
相关资源
最近更新 更多