2011-05-12 142 views
2

代碼C++指針數組

#include "stdafx.h" 
#include <iostream> 

void someFunc(double* pDoubleArray, int length) 
{ 
    double* pNewDoubleArray = new double[length]; 

    for(int i = 0; i < length; i++) 
    { 
     pNewDoubleArray[i] = i * 3 + 2; 
    } 

    pDoubleArray = pNewDoubleArray; 
} 
int main() 
{ 
    double dbls[] = { 1, 2, 3, 4, 5 }; 

    int length = sizeof dbls/sizeof dbls[0]; 

    std::cout << "Before..." << std::endl; 

    for(int i = 0; i < length; i++) 
    { 
     std::cout << dbls[i] << ", "; 
    } 

    std::cout << std::endl; 

    someFunc(dbls, length); 

    std::cout << "After..." << std::endl; 

    for(int i = 0; i < length; i++) 
    { 
     std::cout << dbls[i] << ", "; 
    } 

    std::cout << std::endl; 

    while(true){ } 

    return 0; 
} 

輸出

Before... 
1, 2, 3, 4, 5, 
After... 
1, 2, 3, 4, 5, 

這裏就是我想要做的事: 1.創建一個數組,並用一些值填充它 2.通行證該數組作爲指向函數的指針,該函數將創建一個新數組並重新分配已傳入新創建數組的數據。 3.打印出更改s

雖然我沒有看到任何變化,但我不知道爲什麼。

+5

嘆息。再一次,std :: vector是你真正想要的。 – 2011-05-12 18:31:53

+1

但是沒有通過引用傳遞'vector '會導致同樣的問題。 – 2011-05-12 18:32:52

+0

你能確認你確實想創建一個新的數組,而不是修改已有的數組嗎?你的'main'函數似乎想要修改原始數組。 – 2011-05-12 18:42:30

回答

1

你的函數someFunc的接口是錯誤的。它應該要求引用指針的地址(或指向指針的指針),以便返回新數組的地址。否則,您只是修改本地值。

void someFunc(double*& pDoubleArray, int length) 
{ 
    double* pNewDoubleArray = new double[length]; 

    for(int i = 0; i < length; i++) 
    { 
    pNewDoubleArray[i] = i * 3 + 2; 
    } 

    pDoubleArray = pNewDoubleArray; 
} 

您的通話主要功能則應該通過它可以修改的值:

int main() 
{ 
    double dbls[] = { 1, 2, 3, 4, 5 }; 
    double* pArray = dbls; 
    // ... 

    someFunc(pArray, length); 
    // ... 

    for(int i = 0; i < length; i++) 
    { 
    std::cout << pArray[i] << ", "; 
    } 
    // ... 
} 
+0

謝謝,這工作。出於好奇 - 雖然我如何將指針傳遞給指針?我嘗試過:void someFunc(double ** pDoubleArray,int length),然後pDoubleArray =(double **)pNewDoubleArray;和someFunc((double **)pArray,length);但這導致了我原來的問題沒有發生變化...... – 2011-05-12 18:49:00

+0

@Storm:你將需要使用'&'操作符:'pArray = &dbls;'得到變量的地址。但請記住,更改對新分配實例的引用通常意味着您將失去對舊數據的引用。如果舊數據也是在堆上創建的(使用'new'關鍵字),這意味着內存永遠不會被回收。 – Groo 2011-05-12 18:53:08

+0

@Groo:我試圖做到:double * pArray = &dbls;並出現錯誤:無法從'double(*)[5]'轉換爲'double *' – 2011-05-12 18:57:13

0

忽略內存泄漏問題,其導致:

void someFunc(double* & pDoubleArray, int length) 
// pass by reference ^^^ the pointer 
+0

數組的名稱可以用作指針的r值,但不是指針的l值。你的「修復」不會編譯。 – 2011-05-12 18:39:38

+0

@Ben Voigt,你對此有正面評價嗎?接受的答案似乎另有說明。 :-) – 2011-05-12 20:59:31

+0

是的,我很積極。接受的答案改變了實際參數,它不再是'dbls'了。 – 2011-05-13 00:27:49

0

線pDoubleArray = pNewDoubleArray;分配指針

無論是本地副本按引用傳遞指針,指針傳遞給它,或返回新值

我更傾向於將返回新值,位這是一個風格問題。

+0

您也可以就地更改值,從而避免分配和泄漏新陣列,當然 – rlc 2011-05-12 18:35:33

0

您不清楚爲什麼您要將舊數組傳遞給不使用它的函數

如果您要更改個別值,那麼創建新數組實例就沒有意義了。如果不是,那麼只需創建一個新數組並返回它。

所以,要麼改變原來的數組:

void someFunc(double* pDoubleArray, int length) 
{ 
    for(int i = 0; i < length; i++) 
    { 
     pDoubleArray[i] = i * 3 + 2; 
    } 
} 

或者從函數返回新的數組:

// this indicates that the returned value is 
// actually a new instance 
double* getNewArray(double* pDoubleArray, int length) 
{ 
    double* pNewDoubleArray = new double[length]; 

    for(int i = 0; i < length; i++) 
    { 
     pNewDoubleArray[i] = i * 3 + 2; 
    } 

    return pNewDoubleArray; 
} 

另一種方法是通過由參考輸入數組,但複雜釋放未使用的實例。

[編輯]

爲了澄清最後這種情況下:

void someFunc(double** pDoubleArray, int length) 
{ 
    double* pNewDoubleArray = new double[length]; 

    for(int i = 0; i < length; i++) 
    { 
     pNewDoubleArray[i] = i * 3 + 2; 
    } 

    *pDoubleArray = pNewDoubleArray; 
} 

void main() 
{ 
    double dbls[] = { 1, 2, 3, 4, 5 }; 
    double* pArray = dbls; 

    // this will change what pArray 
    // points to 
    someFunc(&pArray, 5); 

    return 0; 
} 

正如我以前評論的,如果pArray指向一個堆之前分配的數組後一種方法會導致內存泄漏呼籲someFunc