uoj icon indicating copy to clipboard operation
uoj copied to clipboard

部分MLE会显示RE

Open vfleaking opened this issue 9 years ago • 5 comments

程序在申请内存时,被操作系统拒绝,malloc返回NULL。一般选手程序不会对申请失败进行判断,从而导致了RE而不是MLE

vfleaking avatar Jul 18 '16 16:07 vfleaking

设置 setrlimit 之后,如果静态数组过大的的话 execve 失败,errno = ENOMEM,如果动态分配内存过大的话 brkmmap 失败,errno = ENOMEM

dramforever avatar Jul 19 '16 01:07 dramforever

这个是程序处理的问题,如果选手程序没有处理 malloc 返回 NULL 的情况,那么就是一个空指针错误。但在这里不应该将 「malloc 返回 NULL」认为是一种「错误」。

Menci avatar Jul 19 '16 11:07 Menci

man malloc 镇层。

The malloc() and calloc() functions return a pointer to the allocated memory, which is suitably aligned for any built-in type. On error, these functions return NULL.


我觉得如果按照 @Menci 的说法的话,动态分配内存出现 MLE 是不可能判出来的,因为我可以比如写一个数据结构,只有当 malloc 返回 NULL 时才会开始回收内存,以求提高效率。

所以似乎写清楚一些?至少 Runtime Error (Memory Limit Exceeded) 是可以确定的。

dramforever avatar Jul 19 '16 12:07 dramforever

如果选手的程序是C++,且用new申请的内存空间超过了rlimit,就会throw掉,所以会把这些MLE判成RE。如果选手的程序是数组开大了、递归太深了、malloc太多了,就能正常判断出MLE。 解决方法: 编译时如果遇到C++代码,先g++ -E 预处理代码,然后把现有的new (std::nothrow)替换new,然后再把new全部替换成new (std::nothrow)。 或者不用setrlimit,然后ptrace跟踪子进程的系统调用,在SYS_brk调用返回时检查一下进程的内存使用大小。

Sam0230 avatar Jul 22 '19 22:07 Sam0230

改库使得malloc失败就是MLE

837951602 avatar Mar 14 '20 14:03 837951602