使用流提取到char指针时出现分段错误

时间:2010-02-24 20:35:30

标签: c++ pointers

我有一个问题。我有以下struct

typedef struct{
    int vin;
    char* make;
    char* model;
    int year;
    double fee;
}car;

然后我有以下方法询问用户制作汽车并将其作为字符指针返回:

char* askMake(){
    char* tempMake = NULL;
    cout << "Enter Make:" << endl;
    cin >> tempMake;
    return tempMake;
}

然后我有一辆临时车struct

car tempCar;

我正试图以这种方式为其分配一个值:

tempCar.make = askMake();

它编译得很好,但我在运行时遇到了分段错误。

6 个答案:

答案 0 :(得分:12)

您尚未为tempMake分配任何内存指向。当您读入数据时,它会将其读入tempMake恰好指向的任意位置。

取消指针并使用std::string来改善生活。

答案 1 :(得分:8)

您必须为tempMake分配内存。

试试这个:

char* askMake(){
    char* tempMake = new char[1024]; //Arbitrary size
    cout << "Enter Make:" << endl;
    cin >> tempMake;
    return tempMake;
}

不要忘记使用delete[]释放您分配的内存。

如果您不希望内存泄漏,可以使用boost :: shared_ptr或boost :: scoped_ptr等智能指针来避免这种情况。您可以详细了解此here

答案 2 :(得分:6)

你真的想在这里使用std :: string而不是char *。问题是您正在尝试将用户输入读入尚未分配的内存(tempMake)。

std::string askMake(){
    std::string tempMake;
    cout << "Enter Make:" << endl;
    cin >> tempMake;
    return tempMake;
}

你也可能想在你的'car'结构中使用std :: string而不是char *。

答案 3 :(得分:1)

你得到一个段错误,因为你正在写一个空指针。您应该为cin创建一个新的内存空间来写入,然后在它返回时复制它。 std::string可以为您完成此操作:

std::string askMake() {
    std::string temp;
    cout << "Enter Make:" << endl;
    cin >> temp;
    return temp;
}

答案 4 :(得分:0)

其他人告诉你需要做些什么来解决当前问题:要么使用new或malloc为tempMake分配空间,要么使用std:string。

您可能不希望从函数返回指向结构成员的指针。虽然您可以在执行此操作时制作正确的代码,但也有很好的理由这样做,这可能不是其中一个实例。问题与所有权有关。如果你通过指针公开变量,那么最终用户可以自由地将那个人传递给其他函数,这些函数可能最终在你想要之前释放它,或者以其他方式改变它。另外,当你决定自己释放内存时会发生什么?如果您的团队中不知道您的代码的人在您删除它后使用该指针值该怎么办?如果没有人释放它并且你一遍又一遍地使用这个结构怎么办?这是内存泄漏。

最好的模型是隐藏此功能是为了不允许直接访问您的类成员,除非绝对必要,否则不要从函数返回指针。在C ++中,我认为最优雅的解决方案是返回一个std :: string。在直接C中,将char **(我们称之为x)传递给函数,并执行此操作:

int askMake(char** x)
{
    char tempMake[100];//or some value you know to be large enough
    cout << "Enter Make:" << endl;
    cin >> tempMake;//i would use cin.get() so you know the length of the string.
    //so let's pretend we have that length in a variable called stringLen.

    *x = new char[stringLen];
    for(int i = 0; x && i < stringLen; i++)
    {
        (*x)[i] = tempMake[i];
    }

    if(x)
       return 0;
    else
       return 1;
}

答案 5 :(得分:0)

正如其他人所说,您使用char*代替std::string给自己额外的工作。如果切换到std::string,它将如下所示:

#include <string>
struct car
{
  int vin;
  std::string make;
  std::string model;
  int year; 
  double fee; 
}; 

std::string askMake()
{
  std::string make;
  cout << "Enter Make:" << endl;
  cin >> make;
  return make;
}

int main()
{
  car tempCar;
  tempCar.make = askMake();
}