[英]Getting empty when using my own strcopy function
void strcopy(char *src, char *dst) {
int len = strlen(src) - 1;
dst = (char*)malloc(len);
while(*src){
*dst = *src;
src++; dst++;
}
*dst = '\0';
}
int main() {
char *src = "hello";
char *dst = "";
strcopy(src, dst);
printf("strcpy:%s\n", dst);
return 0;
}
Output:
strcpy:
誰能解釋我的strcopy函數出了什么問題? 但是如果在main
執行malloc
,我將得到正確的輸出。 困惑,因為malloc僅在堆中分配內存?
就你而言
strcopy(src, dst);
dst
本身通過值傳遞。 您不能在函數內部分配內存,並且不能期望內存會在調用方函數中反映出來 。
如果要在strcopy()
內存分配給dst
,則需要
dst
。 或者,您也可以從函數中return
新分配的dst
並將其收集回調用方的dst
中。
但是,請記住,當您自己分配內存時,有責任free()
它。
否則,您可以在調用方( main()
)函數內部的dst
分配內存,然后將已經分配的dst
傳遞給函數以執行復制作業。 恕我直言,這種方法與庫函數strcpy()
更相似,因為API本身不處理目標內存的分配。
注意::在代碼中表示
int len = strlen(src) - 1;
您面臨邏輯錯誤。 應該是
int len = strlen(src) + 1;
也要累積終止null。
那里有一些問題:
在strcopy
執行此strcopy
:
dst = (char*)malloc(len);
您將使用新的指針覆蓋 dst
參數中的指針。 這有沒有影響對所有 dst
的主要變量,因為它的價值 ,而不是對它的引用,被傳遞到strcopy
。 因此,當您打印出main
的dst
指向的字符串時,它自然不變,並且仍然是""
。
您沒有為副本分配足夠的內存。 您已經完成:
int len = strlen(src) - 1; dst = (char*)malloc(len);
它分配的兩個字節太少 。 您需要+ 1
,而不是- 1
:源字符串( strlen(src)
)中的字符數, 再加上一個用於終止空字符。
您正在分配從未釋放的內存。
請記住,它是這樣寫的:
正如你們
malloc
,所以必向你free
#2不容易受到使用固定+ 1
,而不是- 1
。
#1有多種固定方式:
您可以讓您的strcopy
為副本分配內存,然后不傳遞dst
並讓它返回分配的指針。 它的文檔會說它做了一個分配,要求調用者將其釋放。 例如:
char * strcopy(char *src) { int len = strlen(src) + 1; char * dst = (char*)malloc(len); for (p = dst; *src; ++p, ++src) { *p = *src; } *p = '\\0'; return dst; } int main() { char *src = "hello"; char *dst = strcopy(src); printf("strcopy:%s\\n", dst); free(dst); // <== note return 0; }
您可以寫入內存main
的dst
指向,但是您需要確保分配足夠的內存。 通常,在C語言中,如果要將緩沖區傳遞到應該寫入緩沖區的函數中,則還傳遞緩沖區的大小,以便函數知道在哪里停止。
您的代碼中有兩件事是錯誤的。
首先,您的strcopy()
函數將strlen(src) - 1
字符分配給dst
,然后將strlen(src) + 1
字符復制到其中。 這給出了不確定的行為。
其次,你main()
通過其本地dst
由值(字符串文字中第一個字符的即地址""
。改變的價值dst
在strcopy()
因此對價值沒有影響dst
在main()
兩個變量(在main()
和strcopy()
)具有相同的名稱這一事實不會改變這一點。
總結其他人的意見和建議,您的代碼可以如下:
void strcopy(char *src, char **_dst) {
int len = strlen(src) + 1;
char *dst = malloc(len);
*_dst= dst;
while(*src){
*dst = *src;
src++; dst++;
}
*dst = '\0';
}
int main() {
char *src = "hello";
char *dst;
strcopy(src, &dst);
printf("strcpy:%s\n", dst);
return 0;
}
這是您要尋找的:
void strcopy(char **src, char **dst) {
int len = strlen(*src) + 1;
*dst = (char*)malloc(len);
int j;
for(j=0;j<strlen(*src);j++)
{
dst[j] = src[j];
}
dst[j] = '\0';
}
int main() {
char *src = "hello";
char *dst = "";
strcopy(&src, &dst);
printf("strcpy:%s\n", dst);
return 0;
}
函數參數是函數的局部變量。 函數處理其參數的副本。 因此,函數中參數的任何更改都不會影響相應參數的原始值。
因此,例如,函數strcopy
此語句
dst = (char*)malloc(len);
不會更改main中定義的參數dst
。
char *dst = "";
如果您確實想編寫一個名為strcopy
的函數,則該函數應處理已分配的數組。 否則,如果函數本身創建源字符串的新副本,則該函數應像strdup
這樣命名。
此外,您的函數是錯誤的,因為當源字符串為空,因此strlen(src)
等於0時,它可以嘗試分配負的內存大小的內存。在任何情況下,它分配的內存都少於所需的內存。
int len = strlen(src) - 1;
dst = (char*)malloc(len);
該功能可以通過以下方式定義
char * strcopy( char *dst, const char *src )
{
char *p = dst;
while ( ( *p++ = *src++ ) );
return dst;
}
叫像
int main( void )
{
char *src = "hello";
char dst[6];
printf( "strcpy:%s\n", strcopy( dst, src ) );
return 0;
}
還應考慮到您不能在C(和C ++)中更改字符串文字。 任何試圖更改字符串文字的嘗試都會導致程序的行為未定義。
因此,您可能不會像例如聲明變量dst
char *dst = "A string literal";
並調用函數strcopy
將dst
作為第一個參數傳遞給上述程序。
如果要創建源字符串的副本,則可以通過以下方式定義函數
char * strdup( const char *src )
{
char *dst = malloc( ( strlen( src ) + 1 ) * sizeof( char ) );
if ( dst )
{
char *p = dst;
while ( ( *p++ = *src++ ) );
}
return dst;
}
叫像
int main( void )
{
char *src = "hello";
char *dst;
dst = strdup( src ) ;
printf( "strcpy:%s\n", dst );
free( dst );
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.