2010-01-29 73 views
0

我寫我自己的字符串複製功能。以下作品:C:缺少一些邏輯與指針的東西

char *src, *dest; 
src = (char *) malloc(BUFFSIZE); 
//Do something to fill the src 
dest = (char *) malloc(strlen(src) + 1); 
mystringcpy(src, dest); 

void mystringcopy(char *src, char *dest) { 
    for(; (*dest = *src) != '\0'; ++src, +dest); 
} 

但是,這並不工作:

char *src, *dest; 
src = (char *) malloc(BUFFSIZE); 
//Do something to fill the src 
mystringcpy(src, strlen(src), dest); 

void mystringcopy(char *src, size_t length, char *dest) { 
    dest = (char *)malloc(length + 1); 
    for(; (*dest = *src) != '\0'; ++src, +dest); 
} 

,我不明白爲什麼...是一個調用的函數內部分配內存的錯誤呢?

+3

* * src =(char *)malloc(BUFFSIZE);'不應該有一個前導'*'。 – spoulson 2010-01-29 19:18:48

+0

什麼是錯誤?除此之外,mystringcopy還沒有定義,除非你有一個原型。 – 2010-01-29 19:19:38

+0

哦,它只是給我一個分段錯誤......我會在第二個檢查其他解決方案... – Legend 2010-01-29 19:23:09

回答

2

你還沒有真正說過「有效」是什麼意思,但我假設你很困惑,爲什麼dest沒有被改回到調用函數中的新內存。

的原因是,在你的mystringcopy功能,參數dest是指針dest在調用函數副本

然後,您將該副本分配給新緩衝區,執行副本,然後副本將消失。原文不變。你需要通過dest作爲指針(指針)。

此外,我假設你寫了你從內存中做了什麼,因爲它不應該按原樣編譯(調用函數中的錯誤解引用)。這裏的固定碼:

char *src, *dest; 
src = (char *)malloc(BUFFSIZE); // no dereference on src, it's a pointer 

//Do something to fill the src 
mystringcpy(src, strlen(src), &dest); // pass the address of dest 

// take a pointer to a char* 
void mystringcopy(char *src, size_t length, char **dest) { 
    // now you should dereference dest, to assign to 
    // the char* that was passed in 
    *dest = (char *)malloc(length + 1); 

    // for simplicity, make an auxiliary dest 
    char* destAux = *dest; 

    // and now the code is the same 
    for(; (*destAux = *src) != '\0'; ++src, ++destAux); 
} 

另一種方法是返回dest指針:

char *src, *dest; 
src = (char *)malloc(BUFFSIZE); 

//Do something to fill the src 
dest = mystringcpy(src, strlen(src)); // assign dest 

char* mystringcopy(char *src, size_t length) { 
    char* dest = (char *)malloc(length + 1); 

    // for simplicity, make an auxiliary dest 
    char* destAux = dest; 

    for(; (*destAux = *src) != '\0'; ++src, ++destAux); 

    return dest; // give it back 
} 

記住,如果長度比源緩衝區,你會溢出目的地緩衝區實際長度小。查看解決方案的評論,儘管這是由您決定的。

+0

非常好的解釋..非常感謝你...還有一個問題是,如果我不想通過這個長度,我假設我將不得不在被調用函數內計算這個值。這是正確的還是將strlen在被調用函數內仍然工作? – Legend 2010-01-29 19:26:57

+0

你可以在函數中使用'strlen'。儘管如此,我實際上將它排除在外。這允許您創建字符串的部分副本,或者提取子字符串。 – GManNickG 2010-01-29 19:29:32

+0

哦......明白......再次感謝...... – Legend 2010-01-29 19:30:32

2

在函數內部分配沒有問題。

問題是在C參數傳遞的價值。所以當你給dest分配一個值的時候,這只是修改本地函數的dest。

你有兩種選擇。您可以返回DEST指針:

char *alloc_and_copy(const char *src, size_t length) 
{ 
    char *dest = malloc(length + 1); 
    ... do your copying 
    return dest; 
} 

,或者你可以傳遞一個指針參數,並修改什麼東西被指出:

void alloc_and_copy(const char *src, size_t length, char **dest) 
{ 
    char *local_dest = malloc(length + 1); 
    ... do your copying using local_dest 

    *dest = local_dest; 
} 

不需要使用本地變量的技術,但我認爲它使更多的可讀代碼。

+0

在修改local_dest之前分配* dest以便遍歷字符串。 – jmucchiello 2010-01-29 19:52:29

+0

@jmucchiello - 這個想法是在local_dest函數中做所有的事情,並且只在最後複製它(否則,它會增加很少的值)。我澄清了我的評論,以使其更加明確。 – 2010-01-29 19:55:42

2

在函數內部做malloc是可以的,但是你沒有把指針從函數中傳遞出去。要麼返回指針:

char * mystringcopy(char *src) 

或指針傳遞到指針:

void mystringcopy(char *src, char **dest) 
1

在一般情況下,分配內存時大概有什麼樣的代碼負責,當它完成釋放內存的某些假設。我贊同一個函數應該對一個主要操作負責的概念,就像一個黑盒子一樣。出於這兩個原因,最好分配你自己的內存,並把指針指向函數來填充它的緩衝區。

除此之外,您可以返回char *指針作爲返回值。

或者,將char *dest參數更改爲char **dest。然後,調用如下函數:mystringcopy(src, strlen(src), *dest)。在函數中,它返回指針:*dest = (char *)malloc(length + 1);。不漂亮。

2

C中的參數是按值傳遞的,所以你的函數獲得dest指針的副本,用malloc覆蓋它,然後丟棄它。試試這個:

void mystringcopy(char *src, size_t length, char **dest) { 
    *dest = (char *)malloc(length + 1); 
    char *p=*dest; 
    for(; (*p = *src) != '\0'; ++src, ++p); 
} 

現在你傳遞一個指針的指針到您的字符串,這樣你就可以在主過程覆蓋。你會使用它:

char *src, *dest; 
*src = (char *) malloc(BUFFSIZE); 
//Do something to fill the src 
mystringcpy(src, strlen(src), &dest); 
// now in dest you have your copy 
相關問題