воскресенье, 1 сентября 2013 г.

Осторожно, многомерные массивы в С!

Наткнулся на интерестную фитчу, честно сказать раньше этого не знал, мб кому-то поможет. Пусть имеется следующий код

 #include <stdio.h>  
 #include <stdlib.h>  
 int main()  
 {  
      char ***buf;  
      char arr[5][4][3];  
      int i, a;  
      arr[4][3][2] = 0x21;  
      buf = (char ***)malloc(sizeof(char **) * 5);  
      for (i = 0; i < 5; i++) {  
           buf[i] = (char **)malloc(sizeof(char *) * 4);  
           for (a = 0; a < 4; a++) {  
                buf[i][a] = (char *)malloc(sizeof(char) * 3);  
           }  
      }  
      buf[4][3][2] = 0x21;  
      printf("%x %x", (int)arr[4][3][2], (int)buf[4][3][2]);  
      getchar();  
      return 0;  
 }  

Тут создаются 2 многомерных массива, один в качестве типа char[5][4][3], а другой как char *** и соответственно заполняется динамически. Мне еще в универе внушили что многомерный массив это указатель на указатель и т.д., следуя данной логике можно предположить что arr и buf, посути одно и тоже, однака хрен там :) Несмотря на то что обращение к элементам этих массивов выглядит одинаково, в памяти они укладываются совершенно разными способами. Массив с типом char *** действительно является указателем на указатель и т.д., однако  char[5][4][3] является указателем на сплошной блок данных и для того чтобы обратится к элементы расчитывается только смещение, без всяких прохождений по цепочке указателей. Вот так вот, как говорится доверяй но проверяй. 

1 комментарий: