linux下的malloc,隐式限制
抱歉,如果标题没有应有的描述性,那么问题很难用几句话来表达。我想知道我在malloc'ing有多少mem可用,如果有效的话,写信给该细分市场。在某些系统(x86_64上的所有linux)上,我在写入2049 mib时会看到SEGFULTS。代码是:linux下的malloc,隐式限制,c,linux,malloc,C,Linux,Malloc,抱歉,如果标题没有应有的描述性,那么问题很难用几句话来表达。我想知道我在malloc'ing有多少mem可用,如果有效的话,写信给该细分市场。在某些系统(x86_64上的所有linux)上,我在写入2049 mib时会看到SEGFULTS。代码是: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <sys/mman.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/mman.h>
int main (int argc, char **argv) {
void *addr;
int megasize = 2100
/// allocate the memory via mmap same result
//addr = mmap ((void *) 0, (size_t) megasize << 20, PROT_READ | PROT_WRITE,
// MAP_PRIVATE | MAP_ANONYMOUS, (int) -1, (off_t) 0);
addr = malloc(megasize << 20);
if (addr == MAP_FAILED) {
fprintf (stderr, "alloc of %d megabytes failed %s\n", megasize,
strerror (errno));
exit (1);
};
printf ("got %d megabytes at %p\n", megasize, addr);
{
int i;
char *p = addr;
printf("touching the %d Mb memory:\n", megasize);
for (i = 0; i < megasize; i++) {
p[i << 20] = 0;
putchar('.');
if (i%64==63) // commenting out this line i see that it really is the 2049th mb
printf(" #%d\n", i);
fflush(stdout);
};
putchar('\n');
};
/// free the memory
munmap (addr, (size_t) megasize << 20);
return 0;
}
有人能告诉我问题出在哪里吗?当通过
int i
进行计数时,您会得到溢出,因为int
在这里有4个字节宽:
p[i << 20] = ...
将来
size\u t
是寻址内存时的首选类型。32位int
无法存储2049 mb的值。您正在通过有符号整数溢出调用未定义的行为,并且碰巧得到一个负数。在大多数32位计算机上,当添加到一个指针上,该指针返回并最终为您提供所需的地址时,意外地。在64位计算机上,这将为您提供一个大约2047 mb的地址,该地址位于内存块的开头(或环绕到64位内存空间的顶部)
使用正确的类型。在这里,
i
应该有类型size\t
,是否启用过限?(这是默认值)sizeof(int)
==4,我相信,int
是有符号的。。。试图获取超过2G的值将导致负偏移。@R。。从技术上讲是正确的,但与乘法不同,GCC目前实际上支持符号位的有符号左移位作为扩展,并且可以相当安全地猜测GCC是使用的编译器。是的,就标准C而言,这是未定义的行为,但#include
@Mat:我不这么认为。我几乎可以肯定的是,我看到过(I=1;I>0;I(@R..:我并没有争辩,你们是对的)形式的代码
p[i << 20] = ...
int i;
size_t i;