2015-10-06 95 views
-9

所有線路在此方案在這裏後崩潰程序:分段錯誤,執行的代碼

#include <stdio.h> 

int main(void) 
{ 
    char ch = 'A'; 
    char* ptr = &ch; 

    ptr[8] = 'B'; 
    printf("ptr[8] = %c\n", ptr[8]); 

    *ptr = 'C'; 
    printf("*ptr = %c\n", *ptr); 
} 

輸出:

ptr[8] = B 
*ptr = C 
Segmentation fault (core dumped) 

我認爲,該方案應在該行ptr[8] = 'B';和崩潰段錯誤,但程序確實執行了所有的代碼行,然後崩潰了,這是我真的沒有得到的。

它不應該在行ptr[8] = 'B';崩潰並停止執行嗎?

+1

-2 !!這是爲什麼 ? –

+1

不幸的是,每次編寫錯誤時,程序都不需要崩潰和刻錄。它可以假裝工作正常,並保存崩潰和燃燒直到另一天。例如,直到您運送了10000個單位之後... – Lundin

回答

9

通過寫入ptr[8],您可能在main這個函數的返回地址上寫了一個字,所以處理器試圖跳到一個奇怪的地方。核心不喜歡它,並採取了巨大的轉儲。

+0

是的,我知道,我只是問爲什麼它沒有在該行代碼處崩潰。這不是導致段錯誤的無效寫入,對吧? –

+0

寫入沒有觸發段錯誤,因爲它是堆棧中的地址。因此內存是可用的(並被堆棧框架使用) – Rerito

+0

@Rerito你澄清了它,我現在明白了。 –

0

它可能有助於分配一些內存變量:

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

int main(void) 
{ 
    char ch = 'A'; 
    char *ptr; 
    if (!(ptr = malloc(sizeof(char) * 100))) 
     return 1; 

    ptr[7] = ch; 
    printf("ptr[8] = %c\n", ptr[7]); 

    ptr[8] = 'B'; 
    printf("ptr[8] = %c\n", ptr[8]); 

    *ptr = 'C'; 
    printf("*ptr = %c\n", *ptr); 

    printf("*ptr = %c\n", ptr[0]); 

    free(ptr); 
} 
1
(gdb) b main 
Breakpoint 1 at 0x400535: file hello.c, line 5. 
(gdb) r 
Starting program: /home/sohil/a.out 

Breakpoint 1, main() at hello.c:5 
5  char ch = 'A'; 
(gdb) c 
Continuing. 

Program received signal SIGSEGV, Segmentation fault. 
0x0000000000400551 in main() at hello.c:9 
9  printf("ptr[8] = %c\n", ptr[8]); 
(gdb) bt 
#0 0x0000000000400551 in main() at hello.c:9 
(gdb) 

你永遠不會SEG在PTR [8] =「C」的任何無效的內存寫入,但是當故障你在printf中訪問它會引起seg錯誤,如gdb所示。

+0

這是在你的系統下。在32位系統下,堆棧結構不同(它也受優化/調試/檢測標誌的影響)。 –

+0

另外,OP的輸出清楚地顯示了一個成功的'printf()':) – Rerito