-9
#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œ> 即带有一些垃圾值的 siva....但是第二个程序显示分段错误...请帮助我找出确切的答案...

#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;
}
4

8 回答 8

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";

如果你真的必须使用 a 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;
}
于 2013-07-12T13:21:50.347 回答
3

您在这里有未定义的行为:

str[i]=name[i];

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

于 2013-07-12T13:15:09.200 回答
3

这有两个问题。

  1. 指针str不指向分配的内存,因此通过它写入是未定义的行为。
  2. 即使它确实指向有效内存,您也没有写入正确数量的数据。复制字符串时,需要复制0末尾的字节,该字节标志着字符串的结束;所以你的循环的上限应该是 bt strlen(name) + 1。或者您可以使用库方法strdup()代替您自己的for循环。

“工作”版本打印一些垃圾字符的原因是0复制字符串的末尾没有告诉iostreams停止打印。“工作”的一个没有崩溃而另一个崩溃的原因纯属愚蠢的运气:str偶然地,垃圾指向您被允许写入的内存,而在崩溃的程序中,它指向不允许写入的内存。就那么简单。

于 2013-07-12T13:18:15.827 回答
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

于 2013-07-12T13:16:05.527 回答
1

str[i]=name[i];是非法的,会导致未定义的行为,因为您没有为str.

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

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

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

你的代码应该是:

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 cause a core dump at the end

于 2013-07-12T13:15:04.310 回答
1

您的代码有几个问题。

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

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

于 2013-07-12T13:20:56.617 回答
0

问题是str[i]=name[i]你必须知道 C++ 不像 Java 或其他一些那样关心内存泄漏。所以你必须为变量或指针分配内存以避免这些问题。已经有很多答案了,你也可以试试

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

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

str[strlen(name)]='\0';
于 2013-07-12T13:40:22.943 回答
0

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

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

int main()
{
    string name = "Siva", str;
    str = name;
    cout << str;
    return 0;
}
于 2013-07-12T13:23:14.290 回答