2010-04-05 79 views
2

這裏有兩個變體。首先:從函數獲取輸出動態分配數組的更好的變體?

int n = 42; 

int* some_function(int* input) 
{ 
    int* result = new int[n]; 
    // some code 
    return result; 
} 

int main() 
{ 
    int* input = new int[n]; 
    int* output = some_function(input); 

    delete[] input; 
    delete[] output; 
    return 0; 
} 

這裏函數返回的是函數內部分配的內存。

第二個變體:

int n = 42; 

void some_function(int* input, int* output) 
{ 
    // some code 
} 

int main() 
{ 
    int* input = new int[n]; 
    int* output = new int[n]; 
    some_function(input, output); 

    delete[] input; 
    delete[] output; 
    return 0; 
} 

這裏的記憶功能外分配。

現在我使用第一個變體。但我知道許多內置的C++函數使用第二個變體。 第一個變種更舒服(在我看來)。但第二個也有一些優點(你在同一個塊中分配和刪除內存)。

也許這是一個愚蠢的問題,但什麼變體更好,爲什麼?

回答

3

我認爲第二個變種更好,因爲你有「對指針的平衡責任」。這使代碼更具可讀性,因爲您可以看到分配的位置以及釋放內存的位置。
如果你想使用第一個變體,我建議你做雙功能some_function_free()。至於malloc/free,new/delete,new[]/delete[]等等。即使它會做簡單的delete[],通過使用這個,當你想要改變你分配內存的方式時,你將節省時間。

1

一般來說,如果切實可行,最好不要堆分配和返回對象。它會產生所有權問題,並使接口複雜化(調用者必須知道如何管理返回對象的使用期限)。這也給內存分配器帶來了更多壓力,這又會造成線程爭用,並且通過更明智地分配空間用於事物,從而拒絕調用者避免此成本的機會。

6

第三變體

const int n = 42; 

template<class It1, class It2> 
void some_function(It1 First, It1 Last, It2 output) 
{ 
    // some code 
} 

void main() 
{ 
    std::vector<int> input(n); 
    std::vector<int> output(n); 
    some_function(input.begin(), input.end(), output.begin()); 

} 
3

既不變體是優選的異常的情況下C++風格,尤其。如果某處發生異常(分配outputsome_function),則一個或兩個動態分配的陣列將泄漏內存。首選的方法是使用資源分配初始化(RAII)概念。安全的C++代碼使用對象來獲取資源。他們的破壞者釋放這些資源。隨着堆棧解除異常,任何獲取到該點的資源都將被安全釋放。

在動態分配陣列的情況下,這意味着std::vector。如果它不會對你的表現產生負面影響(如果你擔心的話,可以簡單介紹一下),你甚至可以通過價值回報。

// don't need the global variable anymore 
std::vector<int> some_function(std::vector<int> &input) 
{ 
    std::vector<int> result; 
    // do something 
    return result; 
} 

int main() // main returns int, not void 
{ 
    std::vector<int> input; 
    // insert some values 
    std::vector<int> output = some_function(input); 
    return 0; 
} 

不再需要擔心誰負責分配和釋放內存。你的代碼變得更清晰和異常安全。

0

第二個好處是它不需要堆分配。您只能使用堆棧分配的內存調用代碼:

int main() 
{ 
    int input[10]; 
    int output[10]; 

    some_function(input, output); 
}