my_strcpy给出了seg错误

时间:2013-10-04 05:22:52

标签: c

#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是“”,它会给我一个分段错误。如果我给它分配它工作正常。给出“”时为什么会给出seg错误。

修改:答案后

#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 =“”,如何处理条件。

5 个答案:

答案 0 :(得分:3)

你问道:“如果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;

答案 1 :(得分:2)

正确:

 if(*dest == '\0'){

应该是:

 if(*(dest - 1) == '\0'){

注意:

 *dest++ = *sour++;

相当于

*dest = *sour;
sour++;
dest++;

您在赋值后递增dest,因此您检查\0在未初始化a[]时存在垃圾值的位置 - 引发未定义的行为。此外,您不会在while循环后返回。

您可以简单地将您的功能编写为:

char* my_strcpy(char* dest,const char* sour){
     if(NULL == dest || NULL == sour)
         return NULL;
    char* d = dest;
     while(*dest++ = *sour++)
        ;
     return d;
}

试一试!!

答案 2 :(得分:2)

在这里:

  1. 将* sour的值分配给* dest
  2. 增加sour和dest所以现在指向下一个字符
  3. 测试* dest现在是NUL退出循环
  4. 如您所见,第3步是从未初始化的内存中读取。您应该测试在递增之前分配的值是否为NUL。

                *dest++ = *sour++;
                if(*dest == '\0'){
                        break;
                }
    

    如果您传入的目标是一个常量字符串,如&#34; &#34;你得到一个段错误,因为字符串常量存储在只读内存中。它们无法修改。

答案 3 :(得分:0)

这是一个简单的版本:

char *my_strcpy(char *d, const char *s){
  int i=0;
  while(d[i++]=*s++)
    /*done inside condition*/;
  return d;
}

答案 4 :(得分:0)

我建议将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;
}

始终避免在同一表达式中使用多个++语句。没有理由这样做,它迟早会给你一些未定义/未指定的行为错误。