linux下的malloc,隐式限制

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

抱歉,如果标题没有应有的描述性,那么问题很难用几句话来表达。我想知道我在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>

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;