2009-02-09 2 views
3

Этот вопрос строит прочь ранее задаваемый вопрос: Pass by reference multidimensional array with known sizeC++ Передача динамически выделенной 2D массив по ссылке

Я пытался выяснить, как получить мои функции, чтобы хорошо играть с 2d массив ссылок. Упрощенная версия моего кода:

unsigned int ** initialize_BMP_array(int height, int width) 
    { 
     unsigned int ** bmparray; 
     bmparray = (unsigned int **)malloc(height * sizeof(unsigned int *)); 
     for (int i = 0; i < height; i++) 
     { 
     bmparray[i] = (unsigned int *)malloc(width * sizeof(unsigned int)); 
     } 
     for(int i = 0; i < height; i++) 
     for(int j = 0; j < width; j++) 
     { 
      bmparray[i][j] = 0; 
     } 
    return bmparray; 
    } 

Я не знаю, как я могу переписать эту функцию так, что она будет работать там, где я прохожу bmparray как пустой неподписанных INT ** по ссылке, чтобы я может выделить пространство для массива в одной функции и установить значения в другом.

ответ

3

Используйте класс, чтобы обернуть его, а затем передавать объекты по ссылке

class BMP_array 
{ 
public: 
    BMP_array(int height, int width) 
    : buffer(NULL) 
    { 
     buffer = (unsigned int **)malloc(height * sizeof(unsigned int *)); 
     for (int i = 0; i < height; i++) 
     { 
     buffer[i] = (unsigned int *)malloc(width * sizeof(unsigned int)); 
     } 

    } 

    ~BMP_array() 
    { 
     // TODO: free() each buffer 
    } 

    unsigned int ** data() 
    { 
     return buffer; 
    } 

private: 
// TODO: Hide or implement copy constructor and operator= 
unsigned int ** buffer 
}; 
+0

Это похоже на много плиты котла, чтобы передать массив. Если он только когда-либо работает с необработанными данными, зачем переносить его в класс? – BigSandwich

+0

Это зависит от того, сколько разных операций выполняется над данными, но я считаю, что даже для операции инициализации и управления памятью стоит использовать класс. – jturcotte

+0

Согласен. Я бы не выделил ресурс, не упаковал его каким-то образом. –

3
typedef array_type unsigned int **; 
initialize_BMP_array(array_type& bmparray, int height, int width) 
1

Чтобы использовать более безопасную и более современную идиому C++, вы должны использовать векторы, а не динамически распределенные массивы.

void initialize_BMP_array(vector<vector<unsigned int> > &bmparray, int height, int width); 
2

Ммм ... может быть, я не очень хорошо понимаю ваш вопрос, но в C вы можете передать «по ссылке», передавая другой уровень указатель разыменования. То есть, указатель на двойной указатель bmparray себя:

unsigned int ** initialize_BMP_array(int height, int width, unsigned int *** bmparray) 
{ 
    /* Note the first asterisk */ 
    *bmparray = (unsigned int **)malloc(height * sizeof(unsigned int *)); 

    ... 

    the rest is the same but with a level of indirection 


    return *bmparray; 
} 

Так память для bmparray зарезервирован внутри функции (а затем передается по ссылке).

Надеюсь, это поможет.

+0

Что делать, если у меня есть функция, я выделять некоторую память с помощью таНос и указатель, на самом деле я простирающийся массив. Теперь я должен передать тот же массив, используя return.Now, я не могу даже освободить его до того, как вернусь. Что я могу сделать в этом случае? –

+0

Вы должны написать две функции, чтобы функция, получающая выделенный массив, освобождала ее. То есть функция, получающая выделенное значение, должна знать, что она должна освободить ее. –

+0

okay.Спасибо. –

Смежные вопросы