简体   繁体   中英

Malloc and array index confusion in C

I was trying to grasp the malloc function in C, and I wrote the following code:

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. 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.

In fact you overwrote 4 memory locations that really weren't set aside for your specific purpose. 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.

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. Other tools, such as valgrind , lint type checkers can also help, but at the end it's up to you.

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. If Java is a Volvo, C is perhaps more like a Ferrari with spotty breaks at times :)

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. At times you may be able to write hundreds of int values, and other times you may not be able to write any extra.

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. 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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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