2014-09-18 22 views
-3

我有以下代碼無法成功運行。 src被分配了一個內存地址,但dest沒有。我使用的Xcode 5命令行開發初學者C:爲什麼兩個變量的初始簽名不同

#include <stdio.h> 
#include <string.h> 

int main() 
{ 
    char* src; 
    char* dest; 

    memcpy(src, "This is source", 15); 
    memcpy(dest, "This is destination", 20); 

    strcat(dest, src); 

    printf("Final destination string : |%s|", dest); 

    return(0); 
} 

聲明之後,SRC的值是「」,並有一個地址,但dest爲NULL。我知道這是一個愚蠢的問題,但需要一些幫助才能做到這一點。

UPDATE 一堆調查後,我一開始就知道我需要初始化的memcpy前指針的空間,雖然Xcode中沒有提供我有用的警告或異常,我可以很容易找到。

正確的用法是使用malloc初始化空間,然後執行memcpy。

char* src; 
char* dest; 
src = malloc(sizeof(char)*15); 
dest = malloc(sizeof(char)*34); 

memcpy(src, "This is source", 15); 
memcpy(dest, "This is destination", 20); 

或者我們也可以使用char數組並在dest上留下足夠的空間。

char src[15]; 
char dest[34]; 

memcpy(src, "This is source", 15); 
memcpy(dest, "This is destination", 20); 
+2

*您的示例中* src'和'dst'都包含垃圾值。他們*不*初始化。無論他們最初碰到什麼都是純粹的事故。您有責任初始化您的變量。沒有人會爲你做。 – AnT 2014-09-18 21:38:43

+0

我現在知道這個問題有一些負面的問題,所以我不能在SF上提出更多的問題。我會感謝你,如果你看到我的更新,請添加回來的點。對於初學者,你不能認爲這是常識,就好像我不應該問。但是Linux和Mac中的警告和錯誤可能會有所不同,並且有些東西不夠直觀,無法解決這個問題。在Xcode中,當您正在查看溢出數組元素時,它將爲您提供值0,該元素很難判斷 – 2014-09-20 18:59:35

回答

1

你的代碼調用未定義的行爲。在初始化它們之前,您正在使用自動存儲變量srcdest的值。

你寫

「的SRC分配一個內存地址」

和這個假設是錯誤的(大感嘆號)。變量是未初始化的,當你以這種方式使用它時會發生任何事情。期間,不討論。

在C程序中有兩種類型的變量:

  • 靜態存儲,這意味着變量使用在連接時被確定的存儲。全局變量和static初始值設定項中的函數變量都屬於那種類型。程序加載時,靜態作用域變量被初始化爲0。

  • 自動存儲,這意味着該變量的存儲開始存在當程序執行

除此之外,C的對象也可以是動態存儲器,其與malloc或其親屬分配的。

這對你意味着什麼? 您必須初始化這些變量。如果將它們放置在靜態存儲中,它們會被初始化爲0,這對於指針來說是一個非常好的值,但是取消引用它(這是您的代碼所做的)是不允許的。因此,您必須將它們初始化爲兼容對象(=內存區域)的地址,該地址與指針的使用相匹配。

1

如果使用指針,使用memcpy之前,必須明確保留或用於存儲字節分配空間要複製在使用malloc(或其他內存分配例程):

char *src = NULL; 

/* add 1 byte for '\0' string terminator... */ 
src = malloc(strlen("This is source") + 1); 
if (!src) { 
    fprintf(stderr, "Error: Could not reserve memory for src pointer\n"); 
    exit(EXIT_FAILURE); 
} 

/* copy over bytes (including terminator byte)... */ 
memcpy(src, "This is source", 15); 

/* do stuff with 'src'... */ 

/* don't forget to free 'src' when you are done with it... */ 
free(src); 

當使用strcat時,目標指針dest也應該被分配了足夠的空間來存儲連接的終止結果。上面的代碼片段應該提供關於如何執行此操作的足夠提示。

+0

,但第一個變量「src」已成功分配值「This is source」,使用dest的相同代碼。爲什麼「dest」不起作用,但「src」起作用 – 2014-09-18 21:30:02

+1

如果一個變量「有效」,這並不重要。如果您沒有爲malloc或類似內存分配例程的指針預先分配足夠的空間,那麼該程序是錯誤的,並且您會觀察到「奇怪」或不一致的行爲,例如您看到的內容。 – 2014-09-18 21:33:35

+0

在繼續之前,您應該閱讀指針和內存分配/釋放。如果你不正確地管理指針存儲器,你正在爲自己的世界而努力。 – 2014-09-18 21:36:18

-2

您需要使用malloc或將指針設置爲現有數組的內存: 您需要這樣做,因爲您的指針現在指向您的內存中的隨機區域,崩潰或一般系統不穩定 即:

src=malloc(80); 

char mem1[160]; 
    src=mem1; 
    dst=mem1+80; 
//

char mem2[89]; 
    dst=mem2; 
+0

這不是如何聲明字符數組,而是使用'char buffer [100]',而不是'char [100] buffer'。 – 2014-09-18 21:52:57

+1

好吧,你是對的它已經超過20年,因爲我寫在C,我會糾正它。儘管我的答案的主要觀點仍然是:使用數組而不是malloc()可以更容易地掌握初學者。 – 2014-09-18 22:07:59

1

您既未初始化src也未初始化dest,因此您不清楚要在哪裏複製字符串文字。 程序有未定義的行爲。

你可以使用數組來做同樣的事情。例如

#include <stdio.h> 
#include <string.h> 

int main(void) 
{ 
    char src[] = "This is source"; 
    char dest[34] = "This is destination"; 


    strcat(dest, src); 

    printf("Final destination string : |%s|", dest); 

    return 0; 
} 

或者另一種方法使用指針

#include <stdio.h> 
#include <string.h> 

int main(void) 
{ 
    const char *s1 = "This is source"; 
    const char *s2 = "This is destination"; 

    char *dest = malloc(strlen(s1) + strlen(s2) + 1); 

    strcat(strcpy(dest, s2), s1); 

    printf("Final destination string : |%s|", dest); 

    free(dest); 

    return 0; 
}