С++: массив переменной длины

Как массивы переменной длины (VLA) занимают место в памяти?

Я заметил, что VLA не занимают непрерывное пространство памяти, может ли кто-нибудь подтвердить то же самое ??

void func(const IplImage *imgSrc, IplImage *imgDest)
{
  uchar *data = (uchar *)imgSrc->imageData;      

  // get the image data
  int height    = imgSrc->height;
  int width     = imgSrc->width;
  int step      = imgSrc->widthStep;
  int stepSobel = imgDest->widthStep;

  //Calculate Sobel of Image  
  uchar *dataSobel = (sobelStart + stepSobel);  

  //**Declaration of VLAs**
  int prevRowBuf[width],curRowBuf[width],nextRowBuf[width];

  for(int j=1;j<(width-1);j++)
  {    
    prevRowBuf[j] = data[j+1]-data[j-1];
    curRowBuf[j]  = data[step+j+1]-data[step+j-1];
  }

  // Some opencv processing
    for() // Some Conditions
    {

        //memcpy(prevRowBuf,curRowBuf,width);
        //memcpy(curRowBuf,nextRowBuf,width);

        //Replaced with
        for(int i=0 ; i< width; i++)
        {
          prevRowBuf[i]=curRowBuf[i];
          curRowBuf[i]=nextRowBuf[i];
        }
    } 
 }

С двумя операциями memcpy моя программа работала только для нескольких начальных индексов VLA. Но после замены memcpy на for Loop моя программа работает нормально для всех индексов VLA.


person techbull    schedule 26.06.2013    source источник
comment
В C++ нет массивов переменной длины. Если я правильно помню, gcc разрешает их в качестве расширения.   -  person Pete Becker    schedule 26.06.2013
comment
Только C99 имеет VLA! C++ и другие версии C могут иметь его как расширение компилятора (что означает, что VLA на самом деле не является частью языка, а является функцией, предоставляемой вашим компилятором).   -  person Nawaz    schedule 26.06.2013
comment
memcpy(prevRowBuf,curRowBuf,width); копирует width байт, а не width intс. Вам нужно memcpy(prevRowBuf,curRowBuf,width * sizeof curRowBuf[324]); (324, конечно, произвольно, вы также можете использовать 0, или -3, или INT_MAX).   -  person Daniel Fischer    schedule 26.06.2013
comment
@DanielFischer: Спасибо за ответ. Теперь программа работает нормально... :D   -  person techbull    schedule 26.06.2013


Ответы (1)


Во-первых, в C++ нет VLA. GCC реализует их как нестандартное расширение.

Теперь, чтобы ответить на ваш вопрос в контексте указанного расширения GCC:

Я заметил, что VLA не занимают непрерывное пространство памяти, может ли кто-нибудь подтвердить то же самое?

Нет, это неправильно. VLA будут занимать постоянное место. Это пространство обычно (всегда?) поступает из стека, а не из памяти кучи, точно так же, как массивы C со статическим размером.

person Konrad Rudolph    schedule 26.06.2013
comment
На данный момент мы знаем, что C++17 — нет. И вряд ли в будущем. - person L. F.; 22.01.2019
comment
@ Л.Ф. Не буду врать, это облегчение. VLA в C уже были банкой червей и, в конечном счете, вероятно, просто плохой идеей для C++, несмотря на их полезность в некоторых сценариях. - person Konrad Rudolph; 22.01.2019
comment
Так что вы можете отредактировать, возможно, часть C++ 17, нет? :) - person L. F.; 22.01.2019
comment
@ Л.Ф. Да, в самом деле. - person Konrad Rudolph; 22.01.2019