如何避免使用malloc?

mor*_*les 18 c malloc

随着最近的噪声C得到,我读到有一些方法可以最大限度地减少C中malloc的使用,这是一个非常好的做法.我怎么也不知道这种做法何时,如何或如何做好.所以我的问题是,也许一些经验丰富的C程序员可以提供一些例子,其中一个人可以(或应该)写一些没有malloc的东西,但对于新手C程序员来说真是不明显的方式(因此说新手只会使用malloc) ?也许你有一些经验可以将malloc分解成其他东西.

PS我读到的一些帖子引用了Quake 3源代码以及它如何避免使用malloc,所以如果有人知道这一点,知道在那里做了什么会很有趣,因为至少知道我想避免挖掘地震代码漫无目的.(因为如果他们避免使用malloc搜索malloc,我认为不会给出太多结果,而且代码库很可能不像单个示例那样简单)

pad*_*ddy 12

我不知道完全避免malloc,但你当然可以减少它.

基本概念是内存池.这是一个已分配的大缓冲区,可用于许多对象,而不是请求大量的小分配.

您可以在实际情况下使用它,在这种情况下,您将事件发送到队列以由另一个线程处理.事件对象可能是小的结构,你真的需要避免malloc每秒都进行数千次调用.

答案当然是从池中绘制这些事件对象.如果需要,您甚至可以使用池缓冲区的一部分来形成列表,以便您可以快速索引已返回池的内存.这些通常称为免费列表.

您必须小心内存对齐,因为您可能会因未对齐的数据而严重影响性能.但是你可以通过一些数学处理所有这些.


不要害怕这些概念.游泳池实际上不一定非常复杂.考虑一下:

int ** matrix = malloc( rows * sizeof(int*) );
for( int i = 0; i < rows; i++ ) {
    matrix[i] = malloc( cols * sizeof(int) );
}
Run Code Online (Sandbox Code Playgroud)

我一直都看到这一点,这是我的一个小小的烦恼.当你能做到这一点时,你为什么要这样做:

int ** matrix = malloc( rows * sizeof(int*) );
matrix[0] = malloc( rows * cols * sizeof(int) );
for( int i = 1; i < rows; i++ ) {
    matrix[i] = matrix[i-1] + cols;
}
Run Code Online (Sandbox Code Playgroud)

当然,这会减少到这一点(请注意第一行中可能的对齐问题 - 为了清楚起见,我在这里忽略了它)

int ** matrix = malloc( rows * sizeof(int*) + rows * cols * sizeof(int) );
matrix[0] = (int*)matrix + rows;
for( int i = 1; i < rows; i++ ) {
    matrix[i] = matrix[i-1] + cols;
}
Run Code Online (Sandbox Code Playgroud)

关于最后一个例子的一件很酷的事情是删除矩阵是多么容易=)

free( matrix );
Run Code Online (Sandbox Code Playgroud)

哦,将矩阵清零也很简单......

memset( matrix[0], 0, rows * cols * sizeof(int) );
Run Code Online (Sandbox Code Playgroud)


Seb*_*ach 5

在局部范围内需要小型、动态大小的数组的情况下, alloca()从堆栈中分配并且不需要显式释放内存(函数返回时它会被释放),并且有可变长度数组( VLA) :

void meh(int s) {
    float *foo = alloca(s * sizeof(float));
    float frob[s];
} // note: foo and frob are freed upon returning
Run Code Online (Sandbox Code Playgroud)