通过C中的calloc分配内存

时间:2016-03-29 13:48:07

标签: c calloc

如果我尝试取消引用一个指针,我只是测试输出是什么,指针指向超出动态创建的内存范围使用calloc()并期待内存错误或一些垃圾值。它给出0作为输出,这是calloc()的基本特征,它用' 0'初始化分配的内存,或者它只是由于未定义的行为?

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int *p = NULL;
    p = (int *)calloc(10, 8);
    if(p != NULL)
    {
        printf("\n successfully allocated memory ");
    } 
    else
        EXIT_FAILURE;
    printf("\n Thirty first element of memory is %d \n",p[30]);
}

结果

successfully allocated memory
Thirty first element of memory is 0

4 个答案:

答案 0 :(得分:1)

从语言的角度来看,访问越界内存是未定义的行为,这意味着任何事情都可能发生。

对于该特定行为的一种可能解释是,大多数操作系统在将任何内存提供给您的进程之前将其清零,与您在内部使用的功能无关(这是一种安全措施,所以你不能读取其他进程使用的数据。

要获取垃圾数据,通常必须在程序内部使用和释放相同的内存(在这种情况下,它会保留旧值)。或者,当然,如果您的索引距离太远以至于您正在索引到相邻的数据结构中。

你的程序没有崩溃的原因是malloc(和类似的函数)通常从os请求更多的内存,而不是你需要的内存,并在下次调用malloc时使用剩余内存。因此,从操作系统的角度来看,您正在访问有效的内存,并且没有理由终止您的程序。

答案 1 :(得分:1)

您仅在p + 30 * sizeof(int)分配p + 120时尝试访问8 * 10 = 80 bytes,因此您可以访问的最大地址为p[19]

答案 2 :(得分:0)

访问超出范围内存的是Undefined Behaviour。因此,您获得的价值可以是01Batman

关键是,你不能对未定义的事情提出任何解释或理由。在这种情况下,任何事情都可能发生。

此外,如果您尝试访问不允许您的程序访问的内存位置,您将获得seg fault。当您访问越界内存时,情况可能并非如此。它可以很好地位于程序的用户存储区域内。

答案 3 :(得分:0)

我认为Windows在释放分配之前会将一个已释放的页面归零。享受下面的代码吧。

#include<stdio.h>
#include<stdlib.h>
#include <windows.h>
#include <signal.h>

int g = 0;
unsigned long long* p=NULL;

void signal_handler(int ssc)
{
    printf("Error %d \n", ssc);
    printf("segfault after %llu bytes",g*8);
    printf("should i go backwards? press enter");
    getch();
    g=0;
    do
    {
        printf("Virtual Adress:%llu is %llu\n",p+g,*(p+g) );
        Sleep(1);
        g--;    
    }
    while(1);
}



int main ()
{

if(SIG_ERR == signal(SIGSEGV, signal_handler) ) {printf("error seting signal handler %d\n",SIGSEGV);}




p = (unsigned long long*)calloc(10,8);

if( p!= NULL)
{
    printf("successfully allocated memory\n");
}
else
{
    EXIT_FAILURE;
}



    do
    {
        printf("Virtual Adress:%llu is %llu\n",p+g,*(p+g) );
        Sleep(2);
        g++;    
    }
    while(1);


    return 0;
}