我正在尝试实施一个简单的筛子,在我的帮助下,我找到了以下代码:
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的代码,不应该也是这样吗?
真的让人困惑。
答案 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那样的硬件强制页面边界。超出您所在地区的行为可以做任何事情!