2017-08-10 105 views
0

我明白當你寫的內存的一部分,你沒有自己發生Abort trap 6,但我意識到一些有趣的事情,而這樣做ķ& [R演習。ç`中止陷阱:6`只有在一定條件下

/* strcat: copies t to the end of s */ 
void _strcat(char *s, char *t) { 
    while (*s != '\0') { 
     s++; 
    } 
    while ((*s++ = *t++) != '\0') { } 
} 

#include <stdio.h> 
int main() { 
    char s[7] = "hello, "; 
    char *t = "world"; 

    _strcat(s, t); 
    printf("%s\n", s); 
    return 0; 
} 

感興趣的部分是char s[7] = "hello, "

當數組的大小爲7,的"hello, "確切長度,Abort trap 6印刷,即使_strcat添加字符以外的存儲器的初始化的部分。

8之間任意數量的 - 12(含)給出了一個Abort trap 6,而包含數字> = 13的罰款。

所以出現了兩個問題:

  1. 爲什麼char s[12] = "hello, "不行的,而7是什麼?看起來像尾數'\0'需要一個大小爲13的數組,但爲什麼7好呢?難道不是8?
  2. 爲什麼7好擺在首位?尺寸8-12包含"hello, "就像7字符大小的數組,並且被寫入超出其原始數組大小,但7得到它,而其他人則沒有。
+0

未定義行爲不必有一致或理智的結果。你調用了未定義的行爲;你會得到你所得到的。 –

+0

@JonathanLeffler哪一部分產生未定義的行爲? – BridgeTheGap

+0

當您將5個字符添加到大小爲7的數組(甚至不是以空字符結尾的字符串)時。 F'r'instance。 –

回答

1

你不得不讀的機器代碼摸不着頭腦。正如Jonathan Leffler所說,這是未定義的行爲。

這可能取決於編譯器,以及如何在內存中規定的東西出來。沒有要求大小爲7的數組獲得實際的7個字節。它可能決定將其填充到16以獲得更好的堆棧佈局。或者它可能會將它放置在不同的位置,因此在它之後有一個零點,而較大的陣列會獲得不同的位置。

或者,如果您在優化時編譯,編譯器可能會將大小爲7的循環展開爲「正確」代碼,該代碼會簡化爲puts("hello, world");,但無法內聯更大的循環。

我在好奇心和Linux上的GCC做了一些小實驗,答案是在64位模式下它總是有效,因爲8字節char *t指針有足夠的空間存儲"world"

在32位模式下它沒有象你所說的,因爲它覆寫返回堆棧。但是有7種工作方式,帶有垃圾數據,因爲在超過返回值之前它不會找到零,然後它會「追加」到打開的堆棧空間中。打印結果看起來像hello, ��#m�?��world

0

我不知道你正在使用的編譯器,但Xcode的抱怨它

Initializer error 初始值設定爲-string字符數組太長

+0

我正在使用gcc編譯器 – BridgeTheGap