C ++ char *问题

时间:2013-07-12 13:13:27

标签: c++

#include<iostream>
using namespace std;
int main()
{
    char *name="Siva",*str;
    for(int i=0;i<strlen(name);i++)
    {
        str[i]=name[i];
    }
    cout<<str;
    return 0;
}

第一个程序给出输出Sivaœ&gt;即含有一些垃圾价值的湿婆.... 但第二个程序显示分段错误...请帮我查一查 确切的答案......

#include<iostream>
using namespace std;
int main()
{
    int i=0;
    char *name="Siva",*str;
    for(i=0;i<strlen(name);i++)
    {
        str[i]=name[i];
    }
    cout<<str;
    return 0;
}

8 个答案:

答案 0 :(得分:5)

char *name="Siva",*str;
for(int i=0;i<strlen(name);i++)
{
str[i]=name[i];
}

str是一个指针,但它还没有指向任何东西。

由于您使用的是C ++,因此您应该使用std::string

#include<iostream>
#include <string>

using namespace std;
int main()
{
  char *name="Siva";
  std::string str;
  for(int i=0;i<strlen(name);i++)
  {
    str += name[i];
  }
  cout<<str;
  return 0;
}

更好的是,摆脱手写的循环:

#include <algorithm>
int main()
{
  char *name="Siva";
  std::string str;
  std::copy (name, name + strlen (name), std::back_inserter (str));
  cout<<str;
  return 0;
}

更好的是,在这个特定的例子中没有理由为什么你需要做任何这些:

char* name = "Silva";
std::string str = name;
cout << str;

顺便说一句,C ++中的字符串文字本质上是const

const char* name = "Silva";

如果你真的必须使用char*,首先我会强烈质疑为什么,然后我会告诉你这样做:

int main()
{
  const char *name="Siva";
  char* str = new char [strlen (name)+1]; // +1 for the null terminator
  strcpy (name, str);
  cout << str;
  delete [] str;
  return 0;
}

我甚至会更强烈地质疑你需要逐字节复制它:

int main()
{
  const char *name="Siva";
  char* str = new char [strlen (name)+1]; // +1 for the null terminator
  for (size_t i = 0; i < strlen (name); ++i )
    str [i] = name [i];
  str [strlen (name)] = '\0';
  cout << str;
  delete [] str;
  return 0;
}

答案 1 :(得分:3)

您在此处有未定义的行为:

str[i]=name[i];

str尚未初始化为任何内容。你写的是你不应该去的地方。

答案 2 :(得分:3)

这有两个问题。

  1. 指针str未指向已分配的内存,因此通过它进行写操作是未定义的行为。
  2. 即使确实指向了有效的内存,也没有写出正确的数据量。复制字符串时,需要复制标记字符串结尾的0字节;所以你的循环的上限应该是strlen(name) + 1。或者您可以使用strdup()之类的库方法,而不是自己的for循环。
  3. “工作”版本打印一些乱码字符的原因是复制字符串末尾没有0告诉iostreams停止打印。 “工作”一个没有崩溃,而另一个没有崩溃的原因是纯粹的愚蠢运气:str中的垃圾,偶然地指向你被允许写入的内存,而在崩溃中程序,它指向你 允许写入的内存。就这么简单。

答案 3 :(得分:2)

这是因为您没有为str分配内存。 (它会导致未定义的行为)

你可以使用像这个例子中的merory分配函数来混合它:

#include<iostream>
using namespace std;
int main()
{
    char *name="Siva",*str;
    // Allocate memory with malloc
    str = (char*)malloc( (strlen(name)+1) * sizeof(char) );
    for(int i=0;i<strlen(name);i++)
    {
        str[i]=name[i];
    }
    str[strlen(name)] = 0;
    cout<<str;
    // Free the allocated memory
    free(str);
    return 0;
}

当你使用c ++时,你可以这样做:

#include<iostream>
using namespace std;
int main()
{
    char *name="Siva",*str;
    // Allocate memory with new
    str = new char[strlen(name) + 1];
    for(int i=0;i<strlen(name);i++)
    {
        str[i]=name[i];
    }
    str[strlen(name)] = 0;
    cout<<str;
    // Free the allocated memory
    delete []str;
    return 0;
}

编辑: 你在输出结束时有一些奇怪的字符的原因是因为你的字符串没有以'\ 0'结尾,它将继续打印它。 (仅当您没有segmentation fault

时才会出现这种情况

答案 4 :(得分:1)

str[i]=name[i];是非法的,导致未定义的行为,因为您没有为str分配内存。

for for循环之前为目标字符串str分配内存:

str = malloc (strlen(name) + 1 );

在for-loop添加终止字符串str[i] = '\0'之后,你也忘记了字符串终止; Undefined behavior指的是行为不可预测的计算机代码。

你的代码应该是:

char *name="Siva", *str;
str = malloc (strlen(name) + 1 ); // mistake 
for(int i=0;i<strlen(name);i++)
{
    str[i]=name[i];
}
str[i] = '\0';  // forgetting 

为了进一步了解,您可以阅读以下答案:strcat() implementation works but causes a core dump at the end

答案 5 :(得分:1)

您的代码存在一些问题。

首先,* str没有被分配,所以它开始时指向指针值开始的任何内存位。

其次,strlen()返回字符串的长度,不包括终止空字符。所以你要做的就是将名称的所有值复制到一些随机的内存中,而不是终止它,然后告诉系统将其打印掉,这可能是任何长度。

答案 6 :(得分:0)

您的问题是使用char数组和指针来表示具有正确字符串类型的语言的字符串。

#include <iostream>
#include <string>
using namespace std;

int main()
{
    string name = "Siva", str;
    str = name;
    cout << str;
    return 0;
}

答案 7 :(得分:0)

问题在于str[i]=name[i]您必须知道C ++不关心memory leaks 像Java或其他一些人。因此,您必须为变量或指针分配内存,以避免这些问题。已经有很多答案,你也可以试试

str=new char[strlen(name)+1];

并且在完成复制时不要忘记使用null终止char数组。在这种情况下

str[strlen(name)]='\0';