2011-10-10 57 views
0

我有學習困難C語言的malloc和指針:C語言 - Malloc無限空間?

我學會爲止:

  • 指針是內存地址的指針。

  • malloc()分配內存位置並返回內存地址。

我試圖創建一個程序來測試malloc和指針,這裏就是我有:

#include<stdio.h> 

main() 
{ 
char *x; 
x = malloc(sizeof(char) * 5); 

strcpy(*x, "123456"); 
printf("%s",*x); //Prints 123456 

} 

我期待一個錯誤,因爲我到malloc提供的大小爲5,其中我把6個字符(123456)放到指針指向的內存位置。這裏發生了什麼?請幫幫我。

更新

在哪裏學習malloc和指針?我很困惑星號的事情,比如何時使用星號等。我不會休息,直到我學會這件事情!謝謝!

回答

5

您正在調用未定義的行爲,因爲您正在寫入(或嘗試寫入)超出已分配內存的範圍。

其他挑剔:

  • 因爲使用strcpy(),你,你在問題權利要求7個複製字節,而不是6。
  • 您打給strcpy()的電話有缺陷 - 您傳遞的是char而不是指向char作爲第一個參數。
  • 如果你的編譯器不抱怨,你沒有使用足夠的警告選項。如果您使用的是GCC,則編譯器命令行中至少需要-Wall
  • 對於strcpy(),您需要包括<stdlib.h>malloc()<string.h>
  • 您還應該明確指定int main()(或更好的是int main(void))。
  • 就個人而言,我足夠老了,我寧願在main()的末尾看到明確的return(0);,即使C99遵循C++ 98並允許您省略它。

您可能不太走運,並在一段時間內調用未定義的行爲,但像valgrind這樣的工具應該指出您的方式錯誤。在實踐中,malloc()的許多實現分配了8個字節的倍數(並且一些是16個字節的倍數),並且假設您微妙地不跨越8個字節的分配,您實際上可能會逃避它。但一個好的調試malloc()valgrind會指出你做錯了。

請注意,由於您沒有free()您從main()返回之前分配的空間,您(相對無害地在這種情況下)泄漏它。還要注意的是,如果複製的字符串更長(比如與字母表相同),並且特別是在嘗試分配內存時嘗試分配其他內存塊,或者在第一個內存塊超過塗鴉後嘗試分配其他內存塊時,則更多很可能會看到你的代碼崩潰。

未定義的行爲是無條件的壞。什麼事情都可能發生。診斷它不需要任何系統。躲開它!

+0

先生,我也嘗試'malloc(1)',並分配「123456」,仍然沒有錯誤。 – dpp

+0

是的 - 因爲'malloc(1)'可能分配了8個字節......並且你沒有調用'free()'。將字符串改爲'「abcdefghijklmnopqrstuvwxyz」'並添加'free()',您很可能會看到它崩潰並燒燬。然而,關於未定義行爲的糟糕之處恰恰在於程序似乎可以在一段時間內使用它 - 然後突然間發現一些讓它們中斷的東西(一個新的平臺,一個新的編譯器,一個額外的函數調用,.. )。 –

+0

+1的牆壁提示 –

0
#include<stdio.h> 

main() 
{ 
char *x; 
x = malloc(sizeof(char) * 5); 

strcpy(x, "123456"); 
printf("%s",x); //Prints 123456 

} 

使用該......它將工作

看到你&礦山程序差異

現在這裏你分配5個字節&寫6字節時這樣6個字節將存儲在下一連續地址。這個額外的字節可以通過內存管理分配給其他字節,所以任何時候這個額外的字節都可以被其他程序改變因爲第6個字節不是你的,因爲你沒有malloc'd這就是爲什麼這叫做undefined行爲

+2

它*可能*工作。 –

+0

我以爲x用於訪問地址容器的內容,* x用於訪問指針指向的內存位置的內容。 – dpp

+0

你是對的,但看到strcpy的第一個argumnent指向字符的syntex。 –

1

首先,有一個問題,您的代碼:

x是一個指針,你5個字符分配空間的存儲區。 * x這是第一個字符的值。 你應該使用strcpy(x,「123456」);

其次,你的5字節分配後的內存可以是有效的,所以你不會收到錯誤。

2

我仙三:

  1. 使用X,如(* x)是(這是未知的,你的情況)存儲在X值 - 你正在寫未知的內存位置。它應該是:

    strcpy(x, "123456");

  2. 其次 - 「123456」,則6個字節,它是7.你忘了尾隨零終止。

  3. 你的程序與它的當前代碼可能工作,但不能保證。

我會怎麼做:

#include<stdio.h> 

main() 
{ 
    char str[] = "123456"; 
    char *x; 
    x = malloc(sizeof(str)); 

    strcpy(x, str); 
    printf("%s",x); //Prints 123456 

    free(x); 
} 
+0

我也嘗試malloc(1),並分配「123456」,仍然沒有錯誤。 – dpp

+0

你沒有崩潰,因爲寫在未知的內存位置是'未定義的行爲'。 –

3

如果你調用malloc你和地址,在堆內存區域。 如果它返回例如1000你的內存應該是這樣的:

Adr Value 
---------- 
1000 1 
1001 2 
1002 3 
1003 4 
1004 5 
1005 6 
1006 0 

在調用strcpy()之後。你寫了7個字符(比分配多了2個)。

X == 1000(指針地址)

* X == 1(解除引用所述值x指向)

沒有從編譯器警告或錯誤消息,因爲C沒有任何範圍檢查。

+0

+1範圍檢查。 –