【问题标题】:Own strncpy() C++自己的 strncpy() C++
【发布时间】:2015-05-14 08:23:37
【问题描述】:

我正在尝试实现我自己的 strncpy() 版本,我从 link 中找到了源代码。

但每次代码到达此代码while((x++ < n) && (*dest++ = *source++));时,我都会遇到Unhandled exception at 0x00411ad5 in exercise 2.exe: 0xC0000005: Access violation writing location 0x00417800.

完整代码如下:

char *strncpy(char * destination, const char * source, size_t n){
        char *dest;
        dest = destination;

        size_t x=0;
        while((x++ < n) && (*dest++  = *source++)); //this is where unhandled exception occurs
        while(x++ < n){
            *dest++ = 0;
        }

        return dest;
    }

int main(){
    char *sample = "blue";
    char * sample2 = "red";

    cout << strncpy(sample, sample2, 5);
    getch();
    return 0;
}

请告诉我为什么会发生这种情况以及我应该如何解决它?谢谢!

【问题讨论】:

  • 您不能覆盖为文字保留的内存。
  • 出现错误是因为你写入了一个只读字符串sample
  • 您不是要返回destination,而不是已经结束的dest吗?

标签: c++ arrays strncpy


【解决方案1】:

您的目的地是"blue",它是一个字符串文字,它是一个常量。因此它位于内存的只读部分(并由本地sample 变量指向),因此写入时出错。

试试这个:

int main(){
    char sample[] = "blue";
    char * sample2 = "red";

    cout << strncpy(sample, sample2, 5);
    getch();
    return 0;
}

这使得sample 成为本地可写内存中的一个数组。

【讨论】:

  • 谢谢,异常已解决。但输出有点奇怪。它没有复制 sample2 中的内容,它给出了奇怪的符号。 -> 已解决,返回错误,应该返回目的地而不是指针。
【解决方案2】:

您不能写入字符串常量 (sample);改为写入char 数组:

int main(){
    char *sample = "blue";
    char buffer[5];

    cout << strncpy(buffer, sample, sizeof(buffer));
    getch();
    return 0;
}

【讨论】:

    【解决方案3】:

    首先,已经向您解释过,您不能覆盖这样定义的字符串。
    其次,如果该函数返回指向复制字符串末尾的指针,则不能使用 cout

    【讨论】:

    • “如果该函数返回指向复制字符串末尾的指针,则不能使用 cout &lt;&lt; strncpy - 但它没有 - 它返回指向字符串开头的指针目标缓冲区,请参阅here
    • 您知道我们在讨论问题中的代码吗?并且该代码返回增加的 dest,而不是 destination
    • 确实,问题的代码现在确实可以做到这一点,但考虑到编写 "my own version of strncpy()" 的目标 - 直到它返回 dest 它仍然有问题,一旦修复返回dest cout 将开始工作。很好的洞察力,尽管现有实现中存在额外的错误。
    【解决方案4】:

    您的程序有两个主要问题 第一个是函数strncpy 必须返回destination 而不是dest

    char *strncpy(char * destination, const char * source, size_t n){
            char *dest;
            dest = destination;
    
            size_t x=0;
            while((x++ < n) && (*dest++  = *source++)); //this is where unhandled exception occurs
            while(x++ < n){
                *dest++ = 0;
            }
    
    //        return dest;
            return destination;
        }
    

    第二个是字符串字面量是不可变的。任何修改字符串文字的尝试都会导致未定义的行为。

    因此main函数应该改写如下

    int main(){
        char sample[] = "blue";
        char * sample2 = "red";
    
        cout << strncpy(sample, sample2, sizeof( sample ) );
    
        getch();
    
        return 0;
    }
    

    使用名称为x 的变量作为计数也是一种不好的编程风格。最好使用例如i

    我会写更简单的函数

    char * strncpy( char *destination, const char *source, size_t n )
    {
            char *dest = destination;
    
            while ( n-- && ( *dest++  = *source++ ) );
            while ( n-- ) *dest++ = '\0';
    
            return destination;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多