Отказ сегментации при использовании потокового извлечения в символьный указатель

У меня есть вопрос. У меня есть следующее 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();

Это компилирует прекрасный, но я получаю отказ сегментации во времени выполнения.

5
задан Robin Daugherty 20 September 2016 в 13:03
поделиться

6 ответов

Я открыл вашу главную страницу в FF с расширением firebug, включил консоль. Эта ошибка возникает настолько быстро, насколько это возможно:

this.GetObj (this.divID) имеет значение null https://server.iad.liveperson.net/hcp/html/mTag.js?site=61775231 Строка 1

this.GetObj (this.divID) имеет значение null https://server.iad.liveperson.net/hcp/html/mTag.js?site=61775231 Строка 1

Может быть, эта функция съедает в циклах процессора?

-121--3199721-

Получение подключаемого модуля scrollTo jQuery . Вы можете просто сделать следующее:

$.scrollTo('div#addnote-area');

Или, если вы хотите анимировать его, укажите число миллисекунд для прокрутки до конца:

$.scrollTo('div#addnote-area', 500);
-121--2426871-

Необходимо выделить память для tempMake .

Попробуйте:

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

Не забудьте освободить удалить [] выделенную память.

Если вы не хотите утечки памяти, вы можете избежать этого с помощью смарт-указателей, таких как boost::shared_ptr, boost::scoped_ptr или подобные. Более подробную информацию об этом можно найти здесь .

8
ответ дан 18 December 2019 в 06:02
поделиться

Вы не выделили память для tempMake , на которую можно было бы указать. Когда вы читаете данные, они считывают их в любое случайное место tempMake , на которое указывает.

Избавьтесь от указателей и используйте вместо них std :: string , чтобы упростить жизнь.

12
ответ дан 18 December 2019 в 06:02
поделиться

Вы действительно хотите использовать здесь std :: string вместо char *. Проблема в том, что вы пытаетесь прочитать вводимые пользователем данные в память (tempMake), которая еще не была выделена.

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

Вы также, вероятно, захотите использовать std :: string вместо char * в своей структуре 'car'.

6
ответ дан 18 December 2019 в 06:02
поделиться

Как говорили другие, вы даете себе дополнительную работу, используя 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();
}
0
ответ дан 18 December 2019 в 06:02
поделиться

Другие рассказали вам, что нужно сделать, чтобы решить непосредственную проблему: либо выделить место для tempMake с помощью new или malloc, либо использовать std: string .

Вероятно, вы не хотите возвращать указатель на член структуры из функции. Хотя при этом вы можете написать правильный код, и для этого есть очень веские причины, это может быть не один из таких случаев. Проблема связана с правом собственности.Если вы открываете переменную с помощью указателя, то конечный пользователь может передать этого парня другим функциям, которые могут в конечном итоге освободить его до того, как вы захотите, или изменить его каким-либо другим способом. Кроме того, что произойдет, если вы решите самостоятельно освободить эту память? Что, если парень из вашей команды, который не знает ваш код, использовал это значение указателя после того, как вы его удалили? Что, если его никто не освободит, и вы будете использовать эту структуру снова и снова? Это утечка памяти.

Лучшая модель, чтобы скрыть эту функциональность, - это запретить прямой доступ к членам вашего класса и не возвращать указатель из функции без крайней необходимости. В C ++ я думаю, что самым элегантным решением было бы вернуть std :: string. В прямом C вместо этого передайте в функцию символ ** (назовем его 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;
}
0
ответ дан 18 December 2019 в 06:02
поделиться

Вы получаете segfault, потому что вы пишете в нулевой указатель. Вы должны создать новое пространство памяти для записи cin, а затем скопировать его, когда он вернется. std :: string может сделать это за вас:

std::string askMake() {
    std::string temp;
    cout << "Enter Make:" << endl;
    cin >> temp;
    return temp;
}
1
ответ дан 18 December 2019 в 06:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: