2017-10-01 31 views
-5

我有這種事:分段故障而使用malloc和採取輸入

int n,m; 
scanf("%d %d",&m,&n); 
int *arr = malloc(sizeof(int)*n*m); 
for(int i=0;i<m*n;scanf("%d",arr+i),i++); 

現在對於比如說N = 2和M = 3,它接受的第一個五年號碼,並提供了有關分段錯誤第六個數字。我在循環之後立即嘗試打印內容,但沒有打印,不知道問題可能是什麼?我廣泛使用了類似的構造,從未遇到過問題。

編輯1: 該問題後來在程序中,但事情是我在循環後立即有一個printf,並沒有打印任何東西,所以我認爲它必須在這裏。爲什麼printf沒有打印什麼?它與平行執行有關嗎?對於壞格式抱歉,我是堆棧溢出新手。

+1

閱讀有關[未定義行爲(https://en.wikipedia.org/wiki/Undefined_behavior)和[緩衝區溢出(HTTPS的另一種方式:// EN .wikipedia.org /維基/ Buffer_overflow)。編譯所有警告和調試信息('gcc -Wall -Wextra -g')。 **使用調試器**'gdb'和[valgrind](http://valgrind.org/)。下次你在SO上提出一些問題時,請給出一些[MCVE](http://stackoverflow.com/help/mcve)。這*修復我的代碼*問題是脫離主題。另請閱讀[文檔](http://en.cppreference.com/w/c),特別是'malloc'和'scanf' –

+6

「這類東西」....請研究[mcve] 。 – Yunnosch

+0

在調試器中檢查'm','n','arr'的值(在'for'循環中有斷點)。我相信你會感到驚訝。 –

回答

1

試試這個,

int n,m; 
printf("Enter two digits"); 
int scanCount = scanf("%d %d", &m, &n); 
if(scanCount < 2){ 
    perror("Input"); 
    exit(EXIT_FAILURE); 
} 
scanCount = 0; 
size_t size = sizeof(int) * n * m; 
int * arr = (int *) malloc(size); 
if (arr == NULL) { 
    perror("malloc"); 
    exit(EXIT_FAILURE); 
}; 
for(int i = 0; i < m * n; i++){ 
    if (scanf("%d", arr + i)) 
     scanCount++; 
} 
if(scanCount < m*n){ 
    perror("Input"); 
    exit(EXIT_FAILURE); 
} 
for(int i=0; i<n*m; i++){ 
    printf("\nValue at %d : %d\n", i, *(arr + i)); 
} 

我已經修改了上面給出的程序一點點,而現在它爲我工作。 的malloc函數期望「的std ::的size_t大小」(我們也可以提供整數值)作爲參數,這是我們需要分配存儲器的大小。請訪問http://en.cppreference.com/w/cpp/memory/c/malloc以供參考。

此外,我們應該指定我們正在創建的存儲器的類型(否則它可能在一些編譯器產生的誤差,這樣「從‘無效*’到‘INT *’無效轉換」)。在這種情況下,我們creting整數的數組,我們可以使用類型cating,例如 爲(int *)malloc的(尺寸)。

最好是通過scanf實施失敗的內存分配和投入一些錯誤處理程序(檢查malloc和scanf函數的返回值)

+3

缺少對'malloc'失敗的檢查:if(arr == NULL){perror(「malloc」); exit(EXIT_FAILURE);};'和'malloc'無用的強制轉換; BTW'scanf'也可能失敗,你的代碼不檢查。回答**以加以改進 –

+0

@BasileStarynkevitch我應該在scanf的情況下檢查什麼? – HariV

+0

瞭解更多關於[scanf](http://en.cppreference.com/w/c/io/fscanf)的信息。計數哪些應該被測試......有時'%n'也是有幫助的 –

1

我試圖運行程序here。沒有錯誤。也許這是巧合,只是碰巧運行,但也許你在打印循環內的值時出錯,如this

如果是這樣,那是因爲最後一次迭代過程中嘗試編寫沒有被分配到使用malloc()的記憶的一部分。類似於arr[6],直到arr[5]實際上在n = 2和m = 3時被分配。這樣做會調用未定義的行爲。看看評論中指出的鏈接@Basil

您必須檢查由malloc()回來發現,如果內存分配成功的價值。如果失敗,則返回NULL

而且scanf()的返回值可以被檢查發現,如果它是成功還是失敗。它返回循環中scanf()必須爲1的成功分配數。如果它不是1發生了一些錯誤。

這是編寫循環

for(i=0;i<m*n && scanf("%d", arr+i)==1;i++);