对于我正在研究的操作系统,我正在设计内核(我将实际上称之为"核心"只是为了与众不同,但它基本相同).如果我无法完成多任务,内存管理和其他基本操作,那么操作系统本身的细节就无关紧要了,所以我需要先解决这个问题.我有一些关于设计malloc例程的任务.
我认为malloc()要么是内核本身的一部分(我倾向于这个),要么是程序的一部分,但是我将不得不编写自己的C标准库实现方式,所以我写了一个malloc.在这方面我的问题实际上相当简单,C(或C++)如何管理它的堆?
我在理论类中一直被教导的是,堆是一个不断扩展的内存块,从指定的地址开始,并且在很多方面表现得像堆栈一样.通过这种方式,我知道在全局范围内声明的变量在开头,并且更多的变量被"推"到堆上,因为它们在各自的作用域中声明,超出作用域的变量只留在内存空间中,但是该空间被标记为空闲,因此如果需要,堆可以扩展更多.
我需要知道的是,C实际上如何以这种方式处理动态扩展堆?编译的C程序是否自己调用malloc例程并处理自己的堆,还是需要为它提供自动扩展的空间?另外,C程序如何知道堆的开始位置?
哦,我知道相同的概念适用于其他语言,但我希望任何示例都在C/C++中,因为我对这种语言最为满意.我也不想担心其他事情,比如堆栈,因为我认为我能够自己处理这样的事情.
所以我想我真正的问题是,除了malloc/free(处理获取和释放页面本身等)之外,程序是否需要操作系统提供其他任何东西?
谢谢!
编辑我更感兴趣的是C如何使用malloc与堆相关而不是在malloc例程本身的实际工作中.如果它有帮助,我在x86上这样做,但C是交叉编译器所以它应该没关系.^ _ ^
进一步编辑:我理解我可能会对术语感到困惑.我被教导说"堆"是程序存储诸如全局/局部变量之类的东西.我习惯于在汇编编程中处理"堆栈",我只是意识到我可能意味着相反.对我的一点研究表明,"堆"更常用于指代程序为自己分配的总内存,或者操作系统提供的内存页面的总数(和顺序).
那么,考虑到这一点,我如何处理不断扩大的堆栈?(看来我的C理论课有点......有缺陷.)
我试图存储在运行时确定的大量布尔信息.我想知道最好的方法是什么.
我目前一直在尝试使用以下方式分配内存:
pStatus = malloc((<number of data points>/8) + 1);
认为这会给我足够的工作量.然后我可以使用数组表示法中的指针引用每个布尔值:
pStatus[element]
不幸的是,这似乎并不是很好.首先,我很难将内存初始化为整数值0.这可以用memset()吗?尽管如此,我认为这不会影响我尝试访问时崩溃的原因pStatus[element].
我也不完全相信这种方法是最好的方法.我真正想要的本质上是一个反映布尔值状态的巨型位掩码.我错过了什么吗?
我试图想出一种在visual c ++(2005)中全局覆盖malloc和相关函数的方法.我的设置是一个带有静态链接的运行时库的DLL,它包含我自己的c ++代码,外部c ++和c代码.我想要完成的是允许dll的用户设置他们自己的内存分配函数的实现.
我不能使用的解决方案:
我不关心的事情
我能想出的最合理的解决方案是以某种方式干扰链接过程并确保我自己的malloc被链接而不是标准的,最好是我希望能够使用旧的malloc函数作为默认值.
在谷歌性能工具中,似乎他们在运行时手动修补函数的代码,以允许在调用原始函数之前调用钩子函数.这真的是最好的方法吗?
我有一个指向Objective-C实例的2D数组,以跟踪地图网格上的游戏对象.现在我将我的代码转换为ARC,Xcode指出了错误.我知道指向对象的指针不允许作为结构成员,但这个让我(差点)措手不及.
我理解ARC约束背后的基本原理,但是:
在网格中查找对象时,我无法负担Objective-C数组的开销
对象本身已经由NSArray同一类中定义的ivar 拥有,该类具有作为ivar的C风格网格; c风格的数组只是一个方便的结构化快捷方式.此外,当从拥有对象中删除对象时NSArray,我将相应的网格槽设置为NULL.
也就是说,2D数组(网格)只是快速(但是愚蠢)指向安全保留在其他地方(NSArrayivar)的对象的集合.
有没有办法摆脱使用演员阵容?例如,将我的网格定义并分配为:
void*** _grid;
Run Code Online (Sandbox Code Playgroud)
代替
MyMapObjectClass*** _grid
Run Code Online (Sandbox Code Playgroud)
在每个插槽中设置或获取指针时,在void*< - > 之间使用(适当桥接)强制转换MyMapObjectClass*?
编辑:所以这就是我如何解决它
我如上所述更改了ivar声明.另外,在设置查找网格的条目时,我这样做了:
// (Done **Only Once** at map initialization)
// _objectArray is an instance of NSMutableArray
MyMapObjectClass* mapObject = [[MyMapObjectClass alloc] init];
// ...configure map object, etc...
// Add to Obj-C array:
[_objectArray addObject:mapObject];
// Add pointer to 2D C array:
_grid[i][j] = (__bridge void*)mapObject;
Run Code Online (Sandbox Code Playgroud)
在(x,y)访问对象时,我做了相反的事情:
MyMapObjectClass* object = (__bridge …Run Code Online (Sandbox Code Playgroud) 我试图在函数中使用malloc返回一个数组:
char* queueBulkDequeue(queueADT queue, unsigned int size)
{
unsigned int i;
char* pElements=(char*)malloc(size * sizeof(char));
for (i=0; i<size; i++)
{
*(pElements+i) = queueDequeue(queue);
}
return pElements;
}
Run Code Online (Sandbox Code Playgroud)
问题是我需要释放它,因为我的MCU堆大小有限.但是我想退回它,所以我不能在功能中释放它,对吧?我可以在函数外部释放已分配的内存(我称之为函数).这有什么最佳做法吗?先感谢您!
可能重复:
Malloc或普通数组定义?
我们了解到C和动态变量中存在动态内存:
#include <stdio.h>
int a = 17;
int main(void)
{
int b = 18; //automatic stack memory
int * c;
c = malloc( sizeof( int ) ); //dynamic heap memory
*c = 19;
printf("a = %d at address %x\n", a, &a);
printf("b = %d at address %x\n", b, &b);
printf("c = %d at address %x\n", *c, c);
free(c);
system("PAUSE");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我如何知道要使用哪种类型的内存?我什么时候该怎么办?
我有一个关于如何分配内存的问题calloc.我看了一下这个问题,但它没有解决在动态分配二维数组的情况下如何分配内存的问题.
我想知道以下三种动态分配2D数组的方式之间的内存表示是否存在差异.
类型1:
double **array1;
int ii;
array1 = calloc(10, sizeof(double *));
for(ii = 0; ii < 10; ii++) {
array1[ii] = calloc(10, sizeof(double));
}
// Then access array elements like array1[ii][jj]
Run Code Online (Sandbox Code Playgroud)
类型2:
double **array1;
int ii;
array1 = calloc(10 * 10, sizeof(double *));
// Then access array elements like array1[ii + 10*jj]
Run Code Online (Sandbox Code Playgroud)
类型3:
double **array1;
int ii;
array1 = malloc(10 * 10, sizeof(double *));
// Then access array elements like array1[ii + 10*jj]
Run Code Online (Sandbox Code Playgroud)
从我所理解的calloc …
编辑完整源代码在这里:
http://code.seanwoods.com/reynard.fossil.cgi/artifact/0cc9cbfbe021c2ba86dcb4d0cf6ada52f0a80063
在这里拨打电话:
http://code.seanwoods.com/reynard.fossil.cgi/artifact/891405e62c95349aaf461dfb8ba82259f77fac9b
我有一个相对简单的内存分配失败.虽然它确实在几个地方分配内存,但应用程序并不是特别复杂.它是C,而不是C++.我很肯定这是一个分配内存的问题,而不是释放内存.
这是代码:
printf(":2 %d %d\n", initial_len, initial_len * sizeof(char));
o->data = (char*) malloc(initial_len * sizeof(char));
printf(":3 \n");
Run Code Online (Sandbox Code Playgroud)
执行后,我得到:
:1
:2 1024 1024
*** glibc detected *** ./menv: corrupted double-linked list: 0x0000000001d14400 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x76d76)[0x7f680cfc4d76]
/lib/x86_64-linux-gnu/libc.so.6(+0x771ed)[0x7f680cfc51ed]
/lib/x86_64-linux-gnu/libc.so.6(+0x794d4)[0x7f680cfc74d4]
/lib/x86_64-linux-gnu/libc.so.6(__libc_malloc+0x70)[0x7f680cfc9b90]
./menv[0x403971]
./menv[0x40391d]
./menv[0x4030ec]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd)[0x7f680cf6cead]
./menv[0x401369]
======= Memory map: ========
00400000-00405000 r-xp 00000000 08:03 2621441 /home/swoods/code/reynard/modules/stdlib/menv
00605000-00606000 rw-p 00005000 08:03 2621441 /home/swoods/code/reynard/modules/stdlib/menv
00606000-00706000 rw-p 00000000 00:00 0
01cfd000-01d3d000 rw-p 00000000 00:00 0 [heap] …Run Code Online (Sandbox Code Playgroud) 我一直在尝试使用MALLOC_MMAP_THRESHOLD_和MALLOC_MMAP_MAX_ env变量来影响长时间运行的Python 2进程中的内存管理.见http://man7.org/linux/man-pages/man3/mallopt.3.html
我从这个错误报告中得到了这个想法:http://bugs.python.org/issue11849
我得到的结果令人鼓舞:内存碎片减少,长时间运行过程中使用的内存中可见的典型高水位标记较低.
我唯一担心的是,当使用这种低级别的调整时,是否还有其他可能会产生副作用的问题.有没有人有使用它们的经验?
下面是一个示例脚本,显示这些变量如何影响生成大型字典的脚本中的RSS内存:https: //gist.github.com/lbolla/8e2640133032b0a6bb9c只需运行"alloc.sh"并比较输出.这是我的输出:
MALLOC_MMAP_THRESHOLD_=None MALLOC_MMAP_MAX_=None
N=9 RSS=120968
MALLOC_MMAP_THRESHOLD_=512 MALLOC_MMAP_MAX_=None
N=9 RSS=157008
MALLOC_MMAP_THRESHOLD_=1024 MALLOC_MMAP_MAX_=None
N=9 RSS=98484
MALLOC_MMAP_THRESHOLD_=2048 MALLOC_MMAP_MAX_=None
N=9 RSS=98484
MALLOC_MMAP_THRESHOLD_=4096 MALLOC_MMAP_MAX_=None
N=9 RSS=98496
MALLOC_MMAP_THRESHOLD_=100000 MALLOC_MMAP_MAX_=None
N=9 RSS=98528
MALLOC_MMAP_THRESHOLD_=512 MALLOC_MMAP_MAX_=0
N=9 RSS=121008
MALLOC_MMAP_THRESHOLD_=1024 MALLOC_MMAP_MAX_=0
N=9 RSS=121008
MALLOC_MMAP_THRESHOLD_=2048 MALLOC_MMAP_MAX_=0
N=9 RSS=121012
MALLOC_MMAP_THRESHOLD_=4096 MALLOC_MMAP_MAX_=0
N=9 RSS=121000
MALLOC_MMAP_THRESHOLD_=100000 MALLOC_MMAP_MAX_=0
N=9 RSS=121008
MALLOC_MMAP_THRESHOLD_=512 MALLOC_MMAP_MAX_=16777216
N=9 RSS=157004
MALLOC_MMAP_THRESHOLD_=1024 MALLOC_MMAP_MAX_=16777216
N=9 RSS=98484
MALLOC_MMAP_THRESHOLD_=2048 MALLOC_MMAP_MAX_=16777216
N=9 RSS=98484
MALLOC_MMAP_THRESHOLD_=4096 MALLOC_MMAP_MAX_=16777216
N=9 RSS=98496
MALLOC_MMAP_THRESHOLD_=100000 MALLOC_MMAP_MAX_=16777216
N=9 RSS=98528
Run Code Online (Sandbox Code Playgroud)
如您所见,对于此示例,使用的RSS比vanilla Python少约20%.
我正在为一项任务实施尾部.我有它正常工作,但我似乎在随机时间免费获得错误.
我无法看到,追踪到一个模式或除了它之外的任何东西是一致的.
例如,如果我将我的程序称为"tail -24 test.in",我将在多次运行时在同一行中得到错误的校验和错误.但是,使用不同的文件,甚至不同的行数打印回来,我会回来没有错误.
关于如何追踪问题的任何想法,我一直试图调试它几个小时无济于事.
这是违规代码:
lines被定义为char**,并且malloc为:
lines = (char**) malloc(nlines * sizeof(char *));
void insert_line(char *s, int len){
printf("\t\tLine Number: %d Putting a %d line into slot: %d\n",processed,len,slot);
if(processed > numlines -1){//clean up
free(*(lines+slot));
*(lines + slot) = NULL;
}
*(lines + slot) = (char *) malloc(len * sizeof(char));
if(*(lines + slot) == NULL) exit(EXIT_FAILURE);
strcpy(*(lines+slot),s);
slot = ++processed % numlines;
}
Run Code Online (Sandbox Code Playgroud)