2012-12-18 25 views
1

我正在寫的矩陣乘法程序,以及保存代碼空間我創建了一個函數make,需要一個指針到一個雙指針和動態地分配給定大小的2維陣列。數組ab初始化爲[-2,2]中的隨機值。但是,當我嘗試在gcc上運行代碼時,出現seg故障。動態分配的數組 - 元素不可訪問

我通過GDB跑的代碼,當我嘗試設置b[0][0]隨機數錯誤出現。當我嘗試在gdb打印b[0][0],我得到的錯誤:

Cannot access memory at address 0xbfebfdc3f5d77f80

不過,我居然能在此之前訪問b[0][0]。我可以在分配數組後無誤地打印數組。出於某種原因,它始終是數組b,似乎會導致問題。

我感覺這是一個指針的問題,但我看不到的地方。我不是那種沒有經驗的程序員,但是我花了2天的時間去了解爲什麼這個錯誤不斷出現。任何人都可以點亮一下嗎?

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 


void make(double ***a, int m, int n) 
{ 
    int i; 
    double *tmp; 


    (*a) = (double **) malloc(m*sizeof(double *)); 
    tmp = (double *) calloc(m*n,sizeof(double)); 

    if(tmp == NULL) 
    { 
    printf("Error with malloc.\n"); 
    exit(EXIT_FAILURE); 
    } 

    for(i=0;i<m;i++) 
    (*a)[i] = &tmp[i*n]; 


    free(tmp); 

    if(a == NULL) 
    { 
    fprintf(stderr, "Error with the matrix, dimensions: %d, %d. \n", m, n); 
    exit(EXIT_FAILURE); 
    } 
} 


int main() 
{ 
    int i, j; 
    int l, m, n; 
    double **a, **b, **c; 

    l = m = n = 8; 

    srand48(time(NULL)); 

    make(&a, l, m); 
    make(&b, m, n); 
    make(&c, l, n); 

    for(i=0; i<l; i++) 
    for(j=0; j<m; j++) 
     a[i][j] = (drand48()*4.0) - 2.0; 

    for(i=0; i<m; i++) 
    for(j=0; j<n; j++) 
     b[i][j] = (drand48()*4.0) - 2.0; 

    free(a); 
    free(b); 
    free(c); 

    return 0; 
} 
+1

除了主要問題馬克·威爾金斯已經低於診斷,注意'如果'make'(一== NULL)'塊提供任何好處因爲你在函數的前面已經解除了'a'的引用。你應該刪除該代碼塊或將其移動到緊跟在'a' – simonc

回答

5

的一個問題是make調用free(tmp)。這是爲陣列分配的內存。如果你打算繼續使用它,它不應該被釋放。

+0

的分配之後呃,我知道它會是一些愚蠢的事情......乾杯! – Cathal

+0

第二雙眼睛有時會有幫助!請注意,爲避免泄漏,該內存在某些時候仍需要釋放。由於它的基地址被分配給一個[0],所以你可以使用它作爲空閒指針(在釋放'a'之前)。或者,你可以(用更棘手的指針數學)將整個數組分配成一個大塊而不是兩個分配。 –

0

您需要在「想成爲二維數組」,你只分配內存的第一行的每一行分配內存,則必須在相同的數據每個指針點。這沒有任何意義。

你不檢查第一malloc調用成功。

你不應該從這個函數中免費調用。

它始終是最好創建一個true 2D array與相鄰分配的存儲單元,而不是某些指針到指針混亂。

0

我已經貼我的部分代碼在這裏

int *nn,*kk; 
int main() 
{ 
int t=0,i; 

scanf("%d",&t); 
int maxx=0; 
nn = new int [t]; 
kk = new int [t]; 
for(i=0;i<t;i++) 
{ 
    scanf("%d%d",&n,&k); 
    nn[i] = n; 
    kk[i] = k; 
    if(maxx<n) 
     maxx=n; 
     cout<<nn[i]<<" "<<kk[i]<<endl; 
} 
t=0; 
for(i=0;i<t;i++) 
{ 
    n = nn[i]; 
    k = kk[i];cout<<nn[i]<<" "<<kk[i]<<endl; 
    //cout<<setprecision(6); 
    if(k<34&&n>k) 
     //cout<<a[n][k]<<endl; 
     printf("%0.7lf\n",a[n][k]); 
    else 
     printf("0.000000\n");//cout<<"0\n"; 
} 
delete []nn; 
delete []kk; 
return 0; 
}