2010-03-22 54 views
0

我有一個2D動態數組。 我輸入線後面的線0的具有最大數量:內存中的未知錯誤C

void InsertZero(int **a, int pos){ 
    int i, j; 
    a = (int**)realloc(a, n * sizeof(*a)); 
    a[n-1] = (int*)calloc(n, sizeof(**a)); 
    d = 0; 
    for(i = n-1; i > pos; i--){ 
     for(j = 0; j < n; j++){ 
      a[i][j] = a[i-1][j]; 
      printf("%d ", a[i][j]); 
     } 
    } 

    for(i = 0; i < n; i++){ 
     a[pos][i] = 0; 
    } 
} 

,如果我做一個大小排列3,5,7,9,......它工作正常。但是,如果行數爲2,4,6,...,它是一個訪問衝突錯誤,當我嘗試打印我的數組:

void Print(void){ 
    int i, j; 
    for(i = 0; i < (n-d); i++){ 
     for(j = 0; j < n; j++){ 
      printf("%d\t", arr[i][j]); 
     } 
     printf("\n"); 
    } 
} 

代碼:http://codepad.org/JcUis6W4

+0

讓我們來詳細談一下這個錯誤,謝爾蓋。你得到的輸出是什麼,你期望的輸出是什麼? – ypnos

+0

當我嘗試讀取一個[0] [0]並且我的數組包含2,4,6,8,...行和colom時,出現訪問衝突錯誤 –

+0

在我看來,您永遠不會初始化任何分開一個[n-1]。所以我不知道你在哪裏設置n,以及你在哪裏調用InsertZero,但我認爲你需要查看這個方向或者在這裏發佈代碼。 – ypnos

回答

0

看着這個我無法理解....看看評論1,你有n設置爲realloc一塊內存,其中aint **類型 - 一個雙指針,你怎麼調用這個函數?其次,評論2,爲什麼當realloc上的雙指針以前被調用時,你叫calloc ......?假設n具有值5,然後,realloc被稱爲雙指針a,意爲a[0][1]..a[4][1],現在calloc因此稱爲a[4]有一個新的內存塊......

 
void InsertZero(int **a, int pos){ 
    int i, j; 

    /* 1. */ 
    a = (int**)realloc(a, n * sizeof(*a)); 
    /* Bzzzzt....if realloc failed, a gets overwritten! */ 

    /* 2. */ 
    a[n-1] = (int*)calloc(n, sizeof(**a)); 

    /* 3. */ 
    d = 0; 

    /* 4. */ 
    for(i = n-1; i > pos; i--){ 
     for(j = 0; j < n; j++){ 
      a[i][j] = a[i-1][j]; 
      printf("%d ", a[i][j]); 
     } 
    } 

    for(i = 0; i < n; i++){ 
     a[pos][i] = 0; 
    } 
} 

評論3,什麼是用於d - 無用的變量? 註釋4,假設n的值爲5,則假定存儲塊的數組下標爲[0][0][4][4]

你能澄清這一切嗎?

編輯:再看一遍......當realloc的呼叫失敗時,a可能被覆蓋!我推薦的這部分代碼來抵消這種

 
    int **tmpA; 
    tmpA = (int**)realloc(a, n * sizeof(*a)); 
    if (tmpA != NULL){ 
     a = tmpA; 
     .... 
     a[n-1] = (int*)calloc(n, sizeof(**a)); 
     for(i = n-1; i > pos; i--){ 
      .... 
     } 

     for(i = 0; i < n; i++){ 
      .... 
     } 
    } 
+0

1)「a」有「n-1」個元素,我用「realloc 2)a [n-1]調用一個新的記憶。 3)我有一個「n-1」行和「n」列。 「d」= 1,(n-d)是(n-1)。當我添加一個新行時,我使d = 0和「n」行和「n」列 4)我知道 –

0

在你的函數InsertZero你有一個局部變量a。這個局部變量最初被設置爲指向一個整數的指針的地址(你可能想要一個指向整數數組的指針的地址,即int ***a)。

當你調用realloc要指定當地的a一個指向的內存塊拷貝,但一旦你與你的函數完成了它是你本地的a副本完全有可能是指向其他不同的地方你的程序。你可能想說*a = (int **)realloc(a, n * sizeof(int *));

危險的是,你使用的是n,它不會傳遞給你的函數。看起來你已經假設n將比前一個數組大1 - 否則你對calloc的調用是多餘的,你只是旋轉數組,讓最後一個元素作爲內存泄漏丟棄。

讓我們使用一個沒有數組的簡單示例,沒有尺寸。比方說,你想創建一個函數:

void make_me_a_pointer(int **mynumber) { 
    *mynumber = (int *)malloc(sizeof(int)); 
    **mynumber = 7; /* assign the value 7 to my allocated memory */ 
} 

int main(void) { 
    int *demoint; 
    make_me_a_pointer(&demoint); 
    printf("Magic num is %d\n", *demoint); 
} 

不過你的情況,你只是分配a = realloc ...,因此從來沒有溝通的a新地址的功能之外。

+0

我有一個「Magic num is 7」 –

+0

嘗試編寫一些簡單的測試代碼Sergey,在使用多維數組和內存分配跳入深度之前,自己熟悉指針...... –

+1

PP有正確的想法。在Sergey的程序中,arr,n和d是全局變量。 arr被賦予指向CreateArray()中分配的指針數組的指針,但是當PP指出時,稍後當您重新分配時,您絕不會將結果賦給全局arr。我猜測,當n是偶數時,realloc必須將塊移到其他地方,所以arr指向已釋放的內存。 您必須檢查* alloc的返回。此調用可能會失敗並返回NULL。你的程序應該處理這個,也許以一個錯誤信息結束。使用有意義的變量名稱,並避免使用全局變量。 – Fred