2011-01-24 2 views
1
template < typename ArrayType > 
ArrayType *VectorToArray(ArrayType **p_ppThisBlock = NULL, vector<ArrayType> *p_vThisVector = NULL) 
{ 
    // Check to see if both parameters are valid. 
    if(p_ppThisBlock == NULL || p_vThisVector == NULL) 
    { 
     return NULL; 
    } 

    else if(p_ppThisBlock != NULL && p_vThisVector != NULL) 
    { 
     // Create the array that will store the vector's elements dynamically. 
     p_ppThisBlock = new ArrayType[ p_vThisVector -> size() ]; 

     // Initialize the array. 
     for(unsigned uIndex(0); uIndex < p_vThisVector -> size(); uIndex++) 
     { 
      p_ppThisBlock[ uIndex ] = p_vThisVector[ uIndex ]; 
     } 

     // Return the pointer that pointing to the new block of memory. Is this relevant? 
     return p_ppThisBlock; 
    } 
} 

Мой вопрос: Является ли возвращаемый блок памяти, который я создал в этой функции, релевантным? (Строка 12).Должен ли я вернуть этот блок памяти?

+8

О мой. Зачем ты это делаешь? Можете ли вы не просто использовать '& v [0]'? На минимальном минимуме обязательно используйте интеллектуальный указатель (с удалением массива); в противном случае этот код, безусловно, не является безопасным. –

+1

И в дополнение к тому, что вы написали, даже не работает правильно: назначение 'p_ppThisBlock = new ArrayType [...]' является несоответствием между 'ArrayType *' и 'ArrayType **' (должно получиться предупреждение компилятора здесь); вы хотите '* p_ppThisBlock = ...'. Аналогично в цикле for вы хотите '(* p_ppThisBlock) [uIndex] = (* p_vThisVector) [uIndex]'. –

+1

Что вы должны делать, если один, но не оба, указатели 'NULL'? например, 'VectorToArray (blck, NULL)'? Сейчас этот случай вообще не обрабатывается. –

ответ

2

В конце концов; отказ сделать это приведет к утечке памяти.

Если функция выделяет массив и оставляет его вызывающему, чтобы освободить память, это нормально. Если вызывающий абонент предполагает, что память освобождается позже (и это не то, что мы видим здесь), утечка памяти.

Почему бы не вернуть vector< vector<ArrayType> >?

EDIT:

Try дает метод следующую подпись.

template <typename ArrayType> 
vector<vector< ArrayType> >& VectorToArray( 
           vector< vector<ArrayType> >& _block, 
           vector<ArrayType>& _vec) 
{ 
    //No need to check parameters 

    //Initialize the array 
    for (unsigned uIndex(0); uIndex < _vec.Size(); uIndex++) 
    { 
     _block.push_back(_vec); 
    } 

    return _block; 
} 

Такой же результат, отсутствие проверки ошибок, отсутствие утечек. Конечно, для этого нужны ссылки вместо необработанных указателей.

+0

Я мог бы сделать, но в моем коде я использую «p_ppThisBlock» (который является внешним по отношению к функции). Должен ли я вернуть «p_ppThisBlock» в конце? – DeadCapacitor

+1

Вместо этого вы можете преобразовать весь метод вместо использования необработанных указателей. Ред. – James

+0

Я никогда раньше не видел вектор векторов. «Vector >» работает так же, как «int Array [0] [0]»? – DeadCapacitor

1

Существуют серьезные проблемы с размещенным кодом. Абсолютная самая очевидная проблема заключается в том, что вы проверяете, были ли переданы два указателя в функцию, и если бы вы указали один из них на что-то другое. Если тот, кто называет вашу функцию, освобождает память, на которую указывает p_ppThisBlock, у вас есть определенная утечка памяти.

Кроме того, с философской точки зрения, вы пытаетесь сделать слишком много в функции (сравните вашу функцию realloc - которая может free память, или ничего не делать, или выделить больше памяти и изменить значение а указатель в зависимости от переданных аргументов).

Однако, чтобы ответить на вопрос, который вы задали, да, это действительно так, чтобы вернуть указатель в память, который вы выделили через new. Именно так выделяется память. Это связано с тем, что есть new.

int* allocateBlockOfIntsUsingAFunction(int numberOfInts) 
{ 
    return new int[numberOfInts]; 
} 

Как уже упоминалось в другой ответ, выделения памяти, а затем не говоря никому это верный путь к утечке памяти:

void leakMemory() 
{ 
    new int[1024]; 
    return; 
} 
int main() 
{ 
    while (true) 
     leakMemory(); 
}