关于malloc函数的问题

时间:2022-03-09 18:48:57
    当malloc函数的输入参数为正数的情况下,有哪些情况可能导致malloc函数发生异常呢?

26 个解决方案

#1


地址空间不够用了。

#2


频繁的分配1M一下的小空间,可能造成堆碎片过多,分配失败

分配超过10M的空间,有些设备上会因内存不足而分配失败

#3


没有连续的空间满足你的要求

#4


   按照我之前看到的资料,当没有连续的空间满足我的需要的时候,系统应该会将函数阻塞,通过移动内存碎片来拼凑出一个足够大的空间来,这样不是不会报错的么?
    我的代码,的确有频繁的申请小空间,基本都在2~200个字节之间,频率的话,大概每秒几十万次的样子,这样会导致malloc报错的么?

#5


    内存空间应该是不可能不足,linux系统应该没有限制单个AP占用的内存上限吧?那样的话,我的机器还有3G的内存处于空闲状态,应该不会内存不足啊

#6


    而且,即使内存不足,它也应该返回一个NULL啊,为什么报错呢

#7


malloc不会抛出异常,直会return NULL。并设置errno
具体设置的错误,你要查编译器手册

In Visual C++ 2005, malloc sets errno to ENOMEM if a memory allocation fails or if the amount of memory requested exceeds _HEAP_MAXREQ. For information on this and other error codes, see errno, _doserrno, _sys_errlist, and _sys_nerr.

#8


引用 4 楼 a220315410 的回复:
按照我之前看到的资料,当没有连续的空间满足我的需要的时候,系统应该会将函数阻塞,通过移动内存碎片来拼凑出一个足够大的空间来,这样不是不会报错的么?
  我的代码,的确有频繁的申请小空间,基本都在2~200个字节之间,频率的话,大概每秒几十万次的样子,这样会导致malloc报错的么?

你这种需求最好用pool,否则光malloc本身的开销你都受不了,至于系统会不会给你移动碎片,这依赖于具体实现,没有跨平台性,不可依赖于此。即便不用pool,你提前开一个大点的缓冲区,所有的读写都在这里面,无论如何,频繁的或循环中malloc肯定不是好的风格,即便你保证没有内存泄露

x86用户空间有限,Windows 默认2G,linux默认3G,实际分配不了那么多

#9


没有释放,用完之后,一定要释放。。。

#10


引用 9 楼 zhangqinhappy 的回复:
没有释放,用完之后,一定要释放。。。

内存泄露不会报异常,只有越界后free或者重复free才会

#11


引用 6 楼 a220315410 的回复:
    而且,即使内存不足,它也应该返回一个NULL啊,为什么报错呢

那恐怕你得看看程序的其他地方是不是写错了……

malloc 失败只应该返回 NULL。

#12


你遇到了什么异常

#13


调试的时候,程序自动的卡在了这行代码上:
unsigned char* newCode = (unsigned char*)malloc(newCodeLength + 1);//这里dataLength为129
这时再点击下一步,程序就会结束。
错误信息貌似是:SIGABRT:Aborted
控制台的输出是:
ReadGif: malloc.c:3096: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.

#14


newCodeLength  这个错了吧

#15


引用 14 楼 limang89 的回复:
newCodeLength  这个错了吧

newCodeLength = 129 应该没错

#16


还是用 valgrind 之类的工具检测一下吧,这种情况一般都是因为之前的内存操作有问题。

#17


我觉的你是不是可以优化一下程序的逻辑
不要那么频繁的操作内存

#18


内存不够用或是没有足够的连续内存,都会导致调用失败。

#19


恩,因为事先无法确定数据的长度,而以最大值去分配内存,又太浪费内存,所以,暂时不知道怎么解决。。。

#20


引用 19 楼 a220315410 的回复:
恩,因为事先无法确定数据的长度,而以最大值去分配内存,又太浪费内存,所以,暂时不知道怎么解决。。。


可以尝试下分配大内存, 浪费总比崩掉好撒

#21


看看返回值就知道了.

#22


man malloc (*^__^*) 嘻嘻……

#23


引用 8 楼 jackyjkchen 的回复:
引用 4 楼 a220315410 的回复:
按照我之前看到的资料,当没有连续的空间满足我的需要的时候,系统应该会将函数阻塞,通过移动内存碎片来拼凑出一个足够大的空间来,这样不是不会报错的么?
我的代码,的确有频繁的申请小空间,基本都在2~200个字节之间,频率的话,大概每秒几十万次的样子,这样会导致malloc报错的么?

你这种需求最好用pool,否则光malloc本身的开销你都受不……

用buffer、pool试试看,在gnu下的话用mcheck试试看是不是内存分配不正常

#24


对,用内存池。

#25


    费了些功夫,采用了一个时间换空间的方案,把内存的频繁申请问题解决了

#26


你好。楼主。我遇到一个和你一样的问题,我是在一个函数里申请内存,其他函数频繁调用这个函数,调用之后释放空间,多次调用,第二次就会出现malloc.c:3096: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
Aborted
时间换空间的方案具体是什么呢?
谢谢

#1


地址空间不够用了。

#2


频繁的分配1M一下的小空间,可能造成堆碎片过多,分配失败

分配超过10M的空间,有些设备上会因内存不足而分配失败

#3


没有连续的空间满足你的要求

#4


   按照我之前看到的资料,当没有连续的空间满足我的需要的时候,系统应该会将函数阻塞,通过移动内存碎片来拼凑出一个足够大的空间来,这样不是不会报错的么?
    我的代码,的确有频繁的申请小空间,基本都在2~200个字节之间,频率的话,大概每秒几十万次的样子,这样会导致malloc报错的么?

#5


    内存空间应该是不可能不足,linux系统应该没有限制单个AP占用的内存上限吧?那样的话,我的机器还有3G的内存处于空闲状态,应该不会内存不足啊

#6


    而且,即使内存不足,它也应该返回一个NULL啊,为什么报错呢

#7


malloc不会抛出异常,直会return NULL。并设置errno
具体设置的错误,你要查编译器手册

In Visual C++ 2005, malloc sets errno to ENOMEM if a memory allocation fails or if the amount of memory requested exceeds _HEAP_MAXREQ. For information on this and other error codes, see errno, _doserrno, _sys_errlist, and _sys_nerr.

#8


引用 4 楼 a220315410 的回复:
按照我之前看到的资料,当没有连续的空间满足我的需要的时候,系统应该会将函数阻塞,通过移动内存碎片来拼凑出一个足够大的空间来,这样不是不会报错的么?
  我的代码,的确有频繁的申请小空间,基本都在2~200个字节之间,频率的话,大概每秒几十万次的样子,这样会导致malloc报错的么?

你这种需求最好用pool,否则光malloc本身的开销你都受不了,至于系统会不会给你移动碎片,这依赖于具体实现,没有跨平台性,不可依赖于此。即便不用pool,你提前开一个大点的缓冲区,所有的读写都在这里面,无论如何,频繁的或循环中malloc肯定不是好的风格,即便你保证没有内存泄露

x86用户空间有限,Windows 默认2G,linux默认3G,实际分配不了那么多

#9


没有释放,用完之后,一定要释放。。。

#10


引用 9 楼 zhangqinhappy 的回复:
没有释放,用完之后,一定要释放。。。

内存泄露不会报异常,只有越界后free或者重复free才会

#11


引用 6 楼 a220315410 的回复:
    而且,即使内存不足,它也应该返回一个NULL啊,为什么报错呢

那恐怕你得看看程序的其他地方是不是写错了……

malloc 失败只应该返回 NULL。

#12


你遇到了什么异常

#13


调试的时候,程序自动的卡在了这行代码上:
unsigned char* newCode = (unsigned char*)malloc(newCodeLength + 1);//这里dataLength为129
这时再点击下一步,程序就会结束。
错误信息貌似是:SIGABRT:Aborted
控制台的输出是:
ReadGif: malloc.c:3096: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.

#14


newCodeLength  这个错了吧

#15


引用 14 楼 limang89 的回复:
newCodeLength  这个错了吧

newCodeLength = 129 应该没错

#16


还是用 valgrind 之类的工具检测一下吧,这种情况一般都是因为之前的内存操作有问题。

#17


我觉的你是不是可以优化一下程序的逻辑
不要那么频繁的操作内存

#18


内存不够用或是没有足够的连续内存,都会导致调用失败。

#19


恩,因为事先无法确定数据的长度,而以最大值去分配内存,又太浪费内存,所以,暂时不知道怎么解决。。。

#20


引用 19 楼 a220315410 的回复:
恩,因为事先无法确定数据的长度,而以最大值去分配内存,又太浪费内存,所以,暂时不知道怎么解决。。。


可以尝试下分配大内存, 浪费总比崩掉好撒

#21


看看返回值就知道了.

#22


man malloc (*^__^*) 嘻嘻……

#23


引用 8 楼 jackyjkchen 的回复:
引用 4 楼 a220315410 的回复:
按照我之前看到的资料,当没有连续的空间满足我的需要的时候,系统应该会将函数阻塞,通过移动内存碎片来拼凑出一个足够大的空间来,这样不是不会报错的么?
我的代码,的确有频繁的申请小空间,基本都在2~200个字节之间,频率的话,大概每秒几十万次的样子,这样会导致malloc报错的么?

你这种需求最好用pool,否则光malloc本身的开销你都受不……

用buffer、pool试试看,在gnu下的话用mcheck试试看是不是内存分配不正常

#24


对,用内存池。

#25


    费了些功夫,采用了一个时间换空间的方案,把内存的频繁申请问题解决了

#26


你好。楼主。我遇到一个和你一样的问题,我是在一个函数里申请内存,其他函数频繁调用这个函数,调用之后释放空间,多次调用,第二次就会出现malloc.c:3096: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
Aborted
时间换空间的方案具体是什么呢?
谢谢