简体   繁体   English

C中的Malloc和数组索引混淆

[英]Malloc and array index confusion in C

I was trying to grasp the malloc function in C, and I wrote the following code: 我试图掌握C中的malloc函数,并编写了以下代码:

int i;

int *arr = (int*)malloc(5*sizeof(int)); 

if(arr==NULL){

  printf("Failed to allocate memory for arr...\n");
  exit(1);

}

I thought this meant that only 5 elements could be added to the array. 我认为这意味着只有5个元素可以添加到数组中。 To test out if that was true, I added the following code: 为了测试这是否属实,我添加了以下代码:

arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr[3] = 4;
arr[4] = 5;
arr[5] = 6;
arr[6] = 7;
arr[7] = 8;
arr[8] = 9;

for(i=0;i<9;i++){

    printf("%d\n",arr[i]);

}

Surprisingly, that code compiled and ran perfectly. 令人惊讶的是,该代码编译并运行完美。 How was that possible? 怎么可能?

C doesn't enforce any array bounds checking, so while you requested space for 5 integers, you used more. C不强制执行任何数组边界检查,因此当您请求5个整数的空间时,您使用了更多。

In fact you overwrote 4 memory locations that really weren't set aside for your specific purpose. 事实上,你覆盖了4个真正没有为你的特定用途预留的内存位置。 Your program went past the area in memory that was set aside for your array, and started to store values in memory outside the allocated region. 你的程序经过了为你的数组预留的内存区域,并开始将值存储在分配区域之外的内存中。

The fact that this "worked" is just pure luck and not something to be dependent on. 事实上,这种“有效”只是纯粹的运气而不是依赖于它。 It may work the next 100 times, or it may fail the next time you try it, with most likely a "segmentation fault" message. 它可能在接下来的100次工作,或者下次尝试时可能会失败,很可能是“分段错误”消息。

Defensive programming, like you did by sensibly checking the return value of malloc, being mindful that you are responsible for bounds checking, compiling code with high warning levels enabled, etc are some of your best defenses to guard against these sort of errors. 防御性编程,就像你通过明智地检查malloc的返回值,注意负责边界检查,编译启用了高警告级别的代码等等,是防御这些错误的一些最好的防御。 Other tools, such as valgrind , lint type checkers can also help, but at the end it's up to you. 其他工具,如valgrind ,lint类型的检查器也可以提供帮助,但最终还是取决于你。

One of C's greatest strengths, its freedom to do all sorts of things, low and high-level, is also one of its greatest weaknesses IMO. C的最大优势之一,它自由地做各种各样的事情,低级和高级,也是IMO最大的弱点之一。 If Java is a Volvo, C is perhaps more like a Ferrari with spotty breaks at times :) 如果Java是沃尔沃,那么C或许更像是法拉利,有时候会有不稳定的突破:)

C不进行边界检查。

How was that possible? 怎么可能?

You're writing past the end of the array. 你正在写过数组的末尾。 This doesn't cause the program to crash (immediately) as there is no bounds checking in C, though, if you write far enough, it will eventually cause a fault. 不会导致程序崩溃 (立即),因为在C中没有边界检查,但是,如果你写得足够远,它最终会导致错误。 At times you may be able to write hundreds of int values, and other times you may not be able to write any extra. 有时您可能会写出数百个int值,有时您可能无法编写任何额外的值。

Memory in your computer is basically laid out sequentially. 计算机中的内存基本上是按顺序排列的。 You asked malloc to give you a small piece of that memory -- enough for 5 ints. 你让malloc给你一小段记忆 - 足够5个整数。 There's definitely more memory available in your computer than it takes to allocate an array of length 5. so if you write to or read from arr[8] , you're writing somewhere else in memory. 计算机中可用的内存肯定比分配长度为5的数组要多。所以如果你写入或读取arr[8] ,你就会在内存中写入其他内容。

Usually, modern computers have so much memory that you're probably writing somewhere that isn't in use. 通常,现代计算机有如此多的内存,你可能正在写一些未使用的地方。 But occasionally, you'll accidentally overwrite some other malloc 'd data. 但偶尔,你会不小心覆盖其他一些malloc数据。

Note that sometimes your program will crash (as you expected). 请注意, 有时您的程序会崩溃(如您所料)。 This is because you might try to write so far outside your allocated memory, that the address isn't valid any more. 这是因为您可能尝试在分配的内存之外写入,该地址不再有效。 Your OS usually catches that and crashes your program for you. 您的操作系统通常会捕获并崩溃您的程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM