- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在将C项目从Linux移植到Windows。在Linux上,它是完全稳定的。在Windows上,大多数情况下都能正常运行,但是有时我遇到了段错误。
我正在使用Microsoft Visual Studio 2010进行编译和调试,看起来有时我的malloc调用根本不分配内存,返回NULL。机器有可用内存;它已经通过了该代码一千次,但仍然发生在不同的位置。
就像我说的,它不会一直或在同一地点发生;它看起来像一个随机错误。
在Windows上,我需要比在Linux上更加谨慎吗?我做错了什么?
最佳答案
malloc()
无法为内存请求提供服务时,它将返回无效的NULL指针。在大多数情况下,C内存分配例程通过调用操作系统来管理内存可用内存的列表或堆,以在进行malloc()
调用且列表或堆上没有块来满足请求时分配其他内存块。 。
因此malloc()
失败的第一种情况是无法满足内存请求,因为(1)C运行时的列表或堆上没有可用的内存块,以及(2)C运行时内存管理请求更多的内存时从操作系统,该请求被拒绝。
这是有关Pointer Allocation Strategies的文章。
本论坛文章提供了malloc failure due to memory fragmentation的示例。malloc()
可能失败的另一个原因是,内存管理数据结构已损坏,可能是由于缓冲区溢出而导致的,在缓冲区溢出中,分配的内存区域用于大于分配的内存大小的对象。不同版本的malloc()
可以使用不同的策略进行内存管理,并确定在调用malloc()
时要提供多少内存。例如,malloc()
可能会为您提供所请求的确切字节数,或者可能为您提供超出您要求的字节数,以便适合在内存边界内分配的块或使内存管理更轻松。
对于现代操作系统和虚拟内存,除非您要进行一些非常大的内存常驻存储,否则要用尽内存是非常困难的。但是,正如用户Yeow_Meng在下面的评论中提到的那样,如果您正在做算术以确定要分配的大小,并且结果为负数,则最终可能会请求大量的内存,因为malloc()
的参数表示要分配的内存量未签名。
在执行指针算术以确定某些数据需要多少空间时,您可能会遇到负数大小的问题。对于非预期文本执行的文本解析,这种错误很常见。例如,以下代码将导致非常大的malloc()
请求。
char pathText[64] = "./dir/prefix"; // a buffer of text with path using dot (.) for current dir
char *pFile = strrchr (pathText, '/'); // find last slash where the file name begins
char *pExt = strrchr (pathText, '.'); // looking for file extension
// at this point the programmer expected that
// - pFile points to the last slash in the path name
// - pExt point to the dot (.) in the file extension or NULL
// however with this data we instead have the following pointers because rather than
// an absolute path, it is a relative path
// - pFile points to the last slash in the path name
// - pExt point to the first dot (.) in the path name as there is no file extension
// the result is that rather than a non-NULL pExt value being larger than pFile,
// it is instead smaller for this specific data.
char *pNameNoExt;
if (pExt) { // this really should be if (pExt && pFile < pExt) {
// extension specified so allocate space just for the name, no extension
// allocate space for just the file name without the extension
// since pExt is less than pFile, we get a negative value which then becomes
// a really huge unsigned value.
pNameNoExt = malloc ((pExt - pFile + 1) * sizeof(char));
} else {
pNameNoExt = malloc ((strlen(pFile) + 1) * sizeof(char));
}
malloc()
和
free()
的依赖就越少。如果您不执行
malloc()
,则失败很困难。
malloc()
的许多小型调用更改为对
malloc()
的较大调用的可能性越大,则使内存碎片和扩展内存列表或堆内存大小的机会就越少,这些小块无法合并,因为它们是不彼此相邻。
malloc()
和
free()
连续块的次数越多,内存管理运行时就可以合并块的可能性就越大。
malloc()
,提供给
malloc()
的size参数可以大于要为其分配内存的对象所需的大小。因此,您可能需要对
malloc ()
调用使用某种规则,以便通过舍入到一些标准内存量来分配标准大小的块。因此,您可以使用((size/16)+ 1)* 16或更可能的((size >> 4)+ 1)<< 4公式来分配16字节的块。许多脚本语言使用类似的东西来增加了重复调用
malloc()
和
free()
的机会,以使请求与列表或内存堆上的空闲块相匹配。
typedef struct __MyNodeStruct {
struct __MyNodeStruct *pNext;
unsigned char *pMegaBuffer;
} MyNodeStruct;
MyNodeStruct *pNewNode = malloc(sizeof(MyNodeStruct));
if (pNewNode)
pNewNode->pMegaBuffer = malloc(15000);
malloc()
提供两个内存区域。
MyNodeStruct *pNewNode = malloc(sizeof(myNodeStruct) + 15000);
if (pNewNode)
pNewNode->pMegaBuffer = ((unsigned char *)pNewNode) + sizeof(myNodeStruct);
pMegaBuffer
指针时保持一致,并且不要在指针上意外地执行
free()
。而且,如果您必须使用更大的缓冲区来更换缓冲区,则需要释放节点并重新分配缓冲区和节点。因此,程序员还有更多工作要做。
关于c - 为什么malloc有时不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12433947/
今天有小伙伴给我留言问到,try{...}catch(){...}是什么意思?它用来干什么? 简单的说 他们是用来捕获异常的 下面我们通过一个例子来详细讲解下
我正在努力提高网站的可访问性,但我不知道如何在页脚中标记社交媒体链接列表。这些链接指向我在 facecook、twitter 等上的帐户。我不想用 role="navigation" 标记这些链接,因
说现在是 6 点,我有一个 Timer 并在 10 点安排了一个 TimerTask。之后,System DateTime 被其他服务(例如 ntp)调整为 9 点钟。我仍然希望我的 TimerTas
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我就废话不多说了,大家还是直接看代码吧~ ? 1
Maven系列1 1.什么是Maven? Maven是一个项目管理工具,它包含了一个对象模型。一组标准集合,一个依赖管理系统。和用来运行定义在生命周期阶段中插件目标和逻辑。 核心功能 Mav
我是一名优秀的程序员,十分优秀!