C ++:为字符指针赋值

时间:2014-06-03 06:31:57

标签: c++ pointers

我已经创建了一个函数,可以将chars从一个ptr指向的位置复制到另一个ptr指向的位置。

我在copy函数中遇到了分段错误。任何人都可以告诉我我的错误是什么

#include<iostream>
using namespace std;
int len(const char* a)
{
    int i=0;
    while(true)
    {
        if(*(a+i)=='\0') return i;
        i++;
    }
}
void cpy(char*s1,const char* s2, int n)
{

    for(int i=0;i<n;i++)
    {
        *(s1+i)=*(s2+i);
    }
}

int main()
{
    const char* a = "honey singh";
    char z = 'v';
    char* b = &z;
    int x=len(a);
    cout<<x<<endl;
    cpy(b,a,x);
} 

我希望copy函数将n个字符从指针a的位置复制到指针b的位置。

我并不关心b的初始值。我只想要一个功能copy(char* b,const char* a,int n),它会将a的前n个字符复制到b    我该怎么做?

4 个答案:

答案 0 :(得分:2)

只有在将字符串创建为char数组时才能执行此操作,而不是使用字符串文字。

char b[] = "hey are you ready";
cpy(b, a);

也可以使用指针b为字符串动态分配内存。

但是在复制时,请注意要复制的字符串的容量。如果将较大的字符串复制到较小的字符串中,它也会产生分段错误。

答案 1 :(得分:0)

问题是b指向单个字符的地址,而不是数组。因此,当您复制所有a字符串时,您将在b指向的对象的边界之外写入,这会产生未定义的行为。您可能会在堆栈中粉碎某些东西,这会导致分段错误。

您需要确保副本的目标大小足以容纳所有源字符串。

char *b = new char[len+1];
cpy(b, a, len);

此外,您的cpy函数应复制n+1个字符,以便复制尾随的空字符。

答案 2 :(得分:0)

激活所有警告(例如使用-Wall):

main.cpp:24:15: warning: deprecated conversion from string constant to 'char*'
     char* b = "hey are you ready";
               ^

最简单的解决方案是使用一组字符代替:

char b[] = "hey are you ready"; // more characters than your original one

关于副本:您想检查source是否实际包含n个字符或事先停止:

void cpy(char * dest, const char* source, int n)
{
    for(int i = 0; *source != '\0' && i < n; ++i)
         // copies n characters or until source has been copied completely
        *dest++ = *source++;
    }
    *dest = '\0';
}

为什么这是必要的

在原始代码中,b是指向字符的指针。现在,指针可以指向存储任何内存地址的任何地方,甚至是那些你不允许更改的内存部分。字符串文字存储在程序*的常量数据部分中。你不允许改变那些东西。但无论哪种方式都可以这样做,最终会出现分段错误。

因此,您需要确保更改不在程序的只读部分中的版本。数组版本就是这样:它初始化一个新数组,它与原始文字具有相同的内容。

顺便说一句,您的编辑也有未定义的行为。现在b指向一个角色。如果要将多个字符复制到b正在寻址的位置,则会写入某个内存,但不会写入实际属于b的内存。这会导致未定义的行为。

最重要的是:不要欺骗编译器

使用C ++,而不是C

但是,您的代码还存在其他一些问题。对于初学者来说,它主要是C.实际使用C ++的唯一部分是cout。如果您使用std::string,您事先就不会遇到这些问题:

#include <iostream>
#include <string>

int main(){
    const std::string a = "honey singh";
    std::string b = "hey are you ready";

    const int n = 5;

    b = a.substr(0, n);
}

如您所见,您的copy已经是标准库的一部分,即std::string::substr

请注意,您的原始代码中还有一些其他损坏的内容,例如copy具有二次运行时而不是线性,copy将太多内容复制到太少内存等等。

答案 3 :(得分:0)

#include<iostream>
#include<cstring>

using namespace std;

int len(const char* a)
{
    int i=0;
    while(true)
    {
        if(*(a+i)=='\0') return i;
        i++;
    }
}

void cpy(char *&s1,const char* s2, int n)
{
  delete [] s1;
  s1=new char[n];
  strncpy(s1,s2,n);
  s1[n]='\0';
}

int main()
{
  const char* a = "honey singh";
  char z = 'v';
  char* b = &z;  
  int x=len(a);
  cout<<x<<endl;

  cpy(b,a,4); //if you want to assign new value to b
  cout<<b<<endl;  //Output will be 'hone'

}