2014-09-12 166 views
0

想象我有以下的C函數:由C函數返回指針陣列

double * cross_product(double vec1[3], double vec2[3]) 
    { 
    double *outvec ; 

    *(outvec + 0)= vec1[1]*vec2[2] - vec1[2]*vec2[1]; 
    *(outvec + 1)= vec1[2]*vec2[0] - vec1[0]*vec2[2]; 
    *(outvec + 2)= vec1[0]*vec2[1] - vec1[1]*vec2[0]; 
    return outvec ; 
} 

爲什麼程序在執行返回一個錯誤,而不是在編譯階段??

這其中也不起作用

double * cross_product_2(double vec1[3], double vec2[3]) 
    { 
    double var ; 
    double *outvec = &var; 

    *(outvec + 0)= vec1[1]*vec2[2] - vec1[2]*vec2[1]; 
    *(outvec + 1)= vec1[2]*vec2[0] - vec1[0]*vec2[2]; 
    *(outvec + 2)= vec1[0]*vec2[1] - vec1[1]*vec2[0]; 
    return outvec ; 
// } 
+0

在第二個例子中,函數結束後,'var'超出了範圍,並且返回的地址不再是有效的內存地址供您使用。還要注意在某個地方,你應該「釋放」記憶。 – crashmstr 2014-09-12 19:00:12

回答

1

double *outvec包含垃圾,因爲您尚未初始化或爲其分配任何值
。 'outvec'上的任何操作都是對垃圾的操作,因此結果也包含垃圾。

校正在第二代碼:

 REVISED CODE 
double * cross_product_2(double vec1[3], double vec2[3]) 
     { 
     double *outvec = NULL; // new change 
     outvec = (double *)malloc(sizeof(double)*3); //since you need space for 3 
                //doubles   


    /* 
      *(outvec + i) means, that the calculated value is to be stored at the ith 
      index of the address pointed to by the outvec pointer. That is how arrays 
       are indexed using pointers 
    */ 
     *(outvec + 0)= vec1[1]*vec2[2] - vec1[2]*vec2[1]; 
     *(outvec + 1)= vec1[2]*vec2[0] - vec1[0]*vec2[2]; 
     *(outvec + 2)= vec1[0]*vec2[1] - vec1[1]*vec2[0]; 
     return outvec ; 
    // } 

說明:

您已經聲明下面的變量 -
雙* outvec;
「outvec」是用來存儲結果將被存儲的地址的指針。作爲變量「outvec」的指針將指向結果將被存儲的地址。 但是既然你沒有指定那個地址是什麼,所以「outvec」指向
某些隨機地址是垃圾。 這就是爲什麼我們需要指定我們要在什麼地址存儲結果,並且爲了這個
我們需要初始化或分配「outvec」變量和一些有效的地址。

+0

好吧,如果我添加這行雙ss; \t double * outvec = &ss; – user3466199 2014-09-12 18:19:11

+0

@ user3466199 - 如果您的指針指向的地址爲 有效,那麼其餘的地方應該落在原地,除非您做出其他 錯誤。 – 2014-09-12 18:36:43

+0

但指向一個雙重和指向一個雙數組有什麼區別,爲什麼我需要聲明一個數組不是一個簡單的雙,因爲如果我在主程序上完成相同的工作,完全工作 – user3466199 2014-09-12 18:48:41

2

您尚未初始化outvec指針,所以你試圖將數據寫入到一個空(或垃圾)地址。試着爲它指定一些內存,或者聲明一個靜態數組以便從你的函數返回。

例如

double *outvec = malloc(3 * sizeof(double)); 

由於在編譯時編譯器不計算outvec,所以會出現運行時錯誤。所以它不知道你將在運行時嘗試訪問什麼地址。

+0

但是我必須在初始化任何指針之前填入任何其他值? – user3466199 2014-09-12 18:14:35

+0

@ user3466199 - 是..爲了在某​​些操作中使用指針,您必須確保它包含有效地址(因爲指針存儲地址爲 ),否則您只對一些隨機內存位置執行 操作: 1.可能不可以是即使在你的流程環境中。 2.包含垃圾。 在這種情況下,如果你幸運的話,你會得到錯誤,如果沒有,你會得到預期的答案。 – 2014-09-12 18:27:32

+0

請看看第二個代碼 – user3466199 2014-09-12 18:31:15

3

你剛剛創建了指針「outvec」,但你不知道它指向的是哪裏。我的意思是,你沒有分配指針outvec將寫入的內存。它只是試圖在隨機存儲器空間上寫入數據。
你需要「告訴」指針中應開始寫入數據,併爲您的工作預留該空間
正如喬爾說,嘗試這樣做,通過使用代碼:

double *outvec = malloc(3 * sizeof(double)); 

對不起儘管我的英語不好......祝你好運!