2012-03-29 84 views
1

可能重複:
What is the difference between char a[] = 「string」 and char *p = 「string」?的memcpy堆棧內存

是什麼堆內存的使用上堆棧內存的memcpy VS之間的區別? 下面的代碼工作在Tru64但段錯誤的LINUX

char * string2 = "   "; 
(void)memcpy((char *)(string2),(char *)("ALT=---,--"),(size_t)(10)); 

第二個版本在Linux上工作

char * string2 = malloc(sizeof(char)*12); 
(void)memcpy((char *)(string2),(char *)("ALT=---,--"),(size_t)(10)); 

有人可以解釋在Linux上段錯誤?

+1

良好閱讀:[是什麼\ [\] =「字符串」與char * p =「字符串」字符之間的區別?(HTTP://計算器。 com/questions/9460260/char-a-string-and-char-p-string之間的區別是什麼) – 2012-03-29 10:26:44

+1

Stack:不是你想的那樣。 – tbert 2012-03-29 10:48:34

+1

您的演員陣容完全濫用,使代碼幾乎無法閱讀。沒有一個是必要的或者甚至是有用的。同樣'sizeof(char)'被定義爲一個。 'malloc'計算大小以'char'的大小來分配。 – 2012-03-29 11:34:38

回答

7

第一個示例具有未定義的行爲。所以它可能正常工作或不顯示任何隨機行爲。

說明:
第一個例子,聲明瞭一個指針string2到字符串文字。字符串文字存儲在實現定義的只讀存儲器位置中。用戶程序不允許修改此內存。任何嘗試這樣做的結果都會導致未定義的行爲

參考:

C99標準6.4.5/5 「字符串文字 - 語義」:

在翻譯階段7中,零值字節或碼被附加到每個多字節字符由一個或多個字符串產生的序列。然後使用多字節字符序列來初始化靜態存儲持續時間和長度的數組,以便足以包含該序列。對於字符串文字,數組元素的類型爲char,並用多字節字符序列的單個字節進行初始化;對於寬字符串,數組元素的類型爲wchar_t,並用寬字符序列初始化...

未指定這些數組是否不同,只要它們的元素具有相應的值。 如果程序試圖修改這樣一個數組,行爲是不確定的。

+1

特別是,字符串'「」'曾被存儲在堆棧中的假設可能是錯誤的。 – caf 2012-03-29 11:40:33

1

在你沒有在棧存儲器中的第一實施例,但.rodata(只讀數據)部分。字符串文字具有靜態存儲持續時間,並且不需要可修改。

void foo(void) 
{ 
    // string array has automatic storage duration 
    char string[] = "   "; 

    // string2 pointer has automatic storage duration and points to 
    // a string literal that a static storage duration 
    char *string2 = "   "; // string2 pointer has 
} 
2

在第一個例子,必須將指針和實際字符串內容之間不同:雖然指針(string2)是在堆棧上,實際的串字節不是。它們在只讀的常量區域有一個很好的變化,因此是段錯誤。

+1

+1用於解決可能的實際混淆源。 – 2012-03-29 14:06:44

0

你的第一個例子改爲:

char string2 [] = "   "; 
(void)memcpy((char *)(string2),(char *)("ALT=---,--"),(size_t)(10)); 

,然後你會與堆內存進行比較堆棧存儲器。

2

首先,行爲是未定義的。從C99開始,6.4.5/6:

未指定這些數組是否不同,只要它們的 元素具有適當的值。如果程序試圖修改這樣一個數組, 的行爲是未定義的。

實際上,操作系統選擇將相關圖像部分加載到只讀存儲器中,因此在嘗試寫入時會出現段錯誤。

1

在第一種情況下,memcpy的目標是字符串文字,正如其他人指出的那樣。

第二種情況:不要投不必要。避免魔術常量。的sizeof(char)的== 1

#include <stdlib.h> 
#include <string.h> 

char * string2 = malloc(1+strlen("ALT=---,--")); 
(void)memcpy(string2, "ALT=---,--"), 1+strlen("ALT=---,--")); 

,這相當於:

char * string2 = malloc(1+strlen("ALT=---,--")); 
(void)strcpy(string2, "ALT=---,--")); 

順便說一句:在原始的,常數 '10' 太小;終止的nul字節不會被複制,並且字符串將被終止。

1

你可以試試這個: char string2[] = " "; (void)memcpy((char *)string2,(char *)("ALT=---,--"),(size_t)(10));