簡體   English   中英

已聲明大小為[x] [y]的數組和另一個大小為[y-1]的數組

[英]Declared array of size [x][y] and another array with size [y-1]

我正在使用Code :: Blocks 10.05和GNU GCC編譯器。

基本上,我在嘗試初始化超出其聲明大小的數組時遇到了一個非常奇怪的問題(對我來說,這是無法解釋的)。 換句話說,就是這樣:

*有一個聲明的數組,大小為[x] [y]。

*還有另一個聲明的數組,其大小為[y-1]。

嘗試將值放入[y-1]大小以外的第二個size [y-1]數組中時出現問題。 嘗試執行此操作時,第一個數組[x][y]將不再保留其所有值。 我只是不明白為什么破壞(或嘗試破壞)一個數組會影響另一個數組的內容。 這是一些示例代碼,它可以看到發生的情況(格式為殘破。要解決此問題,只需將array2[4]更改為array2[5] (這樣就可以消除我所指出的問題)。

#include <stdio.h>

int main(void)
{
    //Declare the array/indices
    char array[10][5];
    int array2[4]; //to see it work (and verify the issue), change 4 to 5
    int i, j;

    //Set up use of an input text file to fill the array
    FILE *ifp;
        ifp = fopen("input.txt", "r");

    //Fill the array
    for (i = 0; i <= 9; i++)
    {
        for (j = 0; j <= 5; j++)
        {
            fscanf(ifp, "%c", &array[i][j]);
            //printf("[%d][%d] = %c\n", i, j, array[i][j]);
        }
    }

    for (j = 4; j >= 0; j--)
    {
        for (i = 0; i <= 9; i++)
        {
            printf("[%d][%d] = %c\n", i, j, array[i][j]);
        }
        //PROBLEM LINE*************
        array2[j] = 5;

    }

    fclose(ifp);
    return 0;

}

那么,有誰知道這是怎么發生或為什么發生的?

因為當您在數組范圍之外進行寫操作時,C可以幫助您。 您只是在寫程序的其他地方。

C被稱為最低級別的高級語言。 要了解“低級”的含義,請記住,您創建的每個變量都可以認為是存在於物理內存中。 如果整數的大小為4,則長度為16的整數數組可能會占用64個字節。也許它們會占用100-163字節(不太可能,但我不會組成實際數字,通常最好以十六進制考慮)。 字節164占用什么? 也許是程序中的另一個變量。 如果您寫入一個由16個整數組成的數組之后會發生什么? 好吧,它可能會寫入該字節。

C讓您執行此操作。 為什么? 如果您想不出任何答案,那么也許應該切換語言。 我不是在書呆子-如果這不能使您受益,那么您可能希望使用一種語言編寫程序,這種語言會使您犯下這樣的怪異錯誤會更加困難。 但是原因包括:

  • 它更快,更小。 添加邊界檢查需要花費時間和空間,因此,如果您要為微處理器編寫代碼或編寫JIT編譯器,那么速度和大小確實很重要。
  • 如果您想了解機器架構並使用硬件,例如,如果您是一名學生,那么它是從編程到OS /硬件/電氣工程的良好門戶。 還有很多計算機科學。
  • 與機器代碼接近,它是許多其他語言和系統必須或可以輕松支持某種程度的兼容性的一種標准。
  • 如果我實際上不得不在接近機器代碼的情況下工作,我將能夠給出其他原因。

道德是:在C語言中,要非常小心。 您必須檢查自己的數組范圍。 您必須清理自己的記憶。 如果不這樣做,您的程序通常不會崩潰,但只會開始做一些很奇怪的事情而不會告訴您在哪里或為什么。

  for (j = 0; j <= 5; j++) 

應該

  for (j = 0; j <= 4; j++)

並且array2最大索引是3所以

  array2[j] = 5;

j == 4時,也是一個問題。

C數組索引從0開始。 因此[X]數組的有效索引是從0X-1 ,因此您總共獲得了X個元素。

為了在數組聲明[X]和表達式< X中都顯示相同的數字,應該使用<運算符而不是<= 例如

  int array[10];
  ...
  for (i=0 ; i < 10 ; ++i) ... // instead of `<= 9`

這不太容易出錯。

如果您不在一個數組的范圍內,則總是有可能您將在另一個數組的范圍內。

array2[j] = 5; -這是您的溢出問題。

for (j = 0; j <= 5; j++) -這也是一個溢出問題。 您也在這里嘗試訪問第5個索引,在此只能訪問第0到第4個索引。

在過程存儲器中,在調用每個函數時,將創建一個激活記錄以保留該函數的所有局部變量,並且還將有更多的存儲器來存儲被調用函數的地址位置。 在您的函數中,有四個局部變量arrayarray2ij 所有這四個將按順序對齊。 因此,如果發生溢出,它將首先嘗試覆蓋上面或下面聲明的變量,具體取決於體系結構。 如果更多字節發生溢出,那么它可能會通過覆蓋某些被調用函數的局部變量來破壞整個堆棧。 這也可能導致崩潰,有時可能不會崩潰,但是您現在所面對的行為會變得無關緊要。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM