[英]my_strcpy gives seg fault
#include<stdio.h>
char* my_strcpy(char*,const char*);
int main(){
char a[20];
char* s = "Hello world!";
char* d = a;
my_strcpy(d,s);
printf("\n d : %s \n",d);
return 0;
}
char* my_strcpy(char* dest,const char* sour){
if(NULL == dest || NULL == sour){
return NULL;
}
while(1){
*dest++ = *sour++;
if(*sour == '\0'){
*dest = *sour;
break;
}
}
}
為什么我們需要char *作為my_strcpy的返回類型。 如果d為“”,則會出現分割錯誤。 如果我給它賦值,它就可以正常工作。 給定“”時,為什么會出現段錯誤。
修改:答案之后
#include<stdio.h>
char* my_strcpy(char*,const char*);
int main(){
char* ret;
char a[20];
char* s = "Hello world!";
char* d = "";
ret = my_strcpy(d,s);
if(NULL == ret){
perror("\nret");
}
// printf("\n d : %s \n",d);
return 0;
}
char* my_strcpy(char* dest,const char* sour){
char* temp;
if(NULL == dest || NULL == sour){
return NULL;
}
temp = dest;
while(1){
*temp++ = *sour++;
if(*sour == '\0'){
*temp = *sour;
break;
}
}
return temp;
}
這仍然會產生段錯誤。 傳遞給函數strcpy時,如果s =“”,該如何處理條件。
您問:“如果d為“,則表示分割錯誤。” 答案:如果為d分配“”或“”,將沒有足夠的空間容納“ Hello World”。 此外,如果將常量字符串分配給標記為數據的內存頁,則可能不允許修改。
您問“為什么我們要把char *作為my_strcpy的返回類型”作為我假定的原始strcpy。 答:您不必。 您可以將void作為返回類型。 但是,如果要執行以下操作,它將變得很實用:
printf ("%s", strcpy (dest, sour));
更正的代碼:
while(1){
*dest++ = *sour++;
if(*(sour-1) == '\0'){
break;
}
或更好:
while(*sour != '\0'){
*dest++ = *sour++;
}
*dest = *sour;
正確:
if(*dest == '\0'){
應該:
if(*(dest - 1) == '\0'){
注意:
*dest++ = *sour++;
相當於
*dest = *sour;
sour++;
dest++;
賦值后,您將增加dest
,因此您在未初始化a[]
情況下在出現垃圾值的位置檢查\\0
導致未定義的行為。 另外,您不會在while循環后返回。
您可以簡單地將函數編寫為:
char* my_strcpy(char* dest,const char* sour){
if(NULL == dest || NULL == sour)
return NULL;
char* d = dest;
while(*dest++ = *sour++)
;
return d;
}
試試看!!
在這里:
如您所見,第3步從未初始化的內存中讀取。 您應該測試在遞增之前分配的值是否為NUL。
*dest++ = *sour++;
if(*dest == '\0'){
break;
}
如果您傳入的目標是一個常量字符串,例如“”,則會出現段錯誤,因為字符串常量存儲在只讀內存中。 它們不能被修改。
這是一個簡單的版本:
char *my_strcpy(char *d, const char *s){
int i=0;
while(d[i++]=*s++)
/*done inside condition*/;
return d;
}
我建議將strcpy實現為:
char* my_strcpy (char* s1, const char* s2)
{
char* return_val = s1;
*s1 = *s2;
while(*s2 != '\0')
{
s1++;
s2++;
*s1 = *s2;
}
return return_val;
}
始終避免在同一表達式中使用多個++語句。 從來沒有理由這樣做,它遲早會給您帶來一些未定義/未指定的行為錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.