malloc vs array,无法理解为什么会这样

时间:2016-10-07 17:55:51

标签: c arrays malloc

我正在尝试实施一个简单的筛子,在我的帮助下,我找到了以下代码:

int main(int argc, char *argv[])
{
    int *array, n=10;
    array =(int *)malloc(sizeof(int));
    sieve(array,n);
    return 0;
}

void sieve(int *a, int n)
{
    int i=0, j=0;

    for(i=2; i<=n; i++) {
        a[i] = 1;
    }
...

出于某种原因,这有效,但我认为不应该!为变量数组分配的空间仅足以支持一个整数,但在函数筛中调用i = 2 ... 10的[i]。这不应该导致问题吗?

我尝试将实现更改为

int array[10], n = 10; 

在运行时导致“Abort trap:6”。但是,我理解这一点,因为数组[10]将在分配的空间之外。但对于我使用malloc的代码,不应该也是这样吗?

真的让人困惑。

1 个答案:

答案 0 :(得分:0)

在某些方面你是对的。例如,这一行:

array =(int *)malloc(sizeof(int));

仅为一个整数分配空间,而不是10.它应该是:

array =(int *)malloc(sizeof(int) * 10);

但是,这并不意味着代码会失败。至少不是立即。当你从malloc返回一个指针然后开始写超出你已分配的范围时,可能在内存中破坏某些东西

也许你正在编写一个malloc使用的结构来跟踪它的要求,也许你正在写别人的内存分配。也许什么都没有 - malloc通常会分配比它要求更多的东西,以保持它可以管理的块。

如果您想要崩溃,通常需要在操作系统页面边界之外进行涂鸦。如果您使用的是Windows或Linux或其他任何东西,操作系统将为您(或本例中为malloc)提供一组块中的一些内存,通常为4096字节。如果你在那个块中乱写,操作系统将无关紧要。如果你走到它外面,你将导致页面错误,操作系统通常会破坏你的过程。

在MS-DOS时代,它更有趣。这不是一个“保护模式”操作系统 - 它没有像Windows或Linux那样的硬件强制页面边界。超出您所在地区的行为可以做任何事情