Печать символа * в C ++ - PullRequest
2 голосов
/ 28 июня 2009

Я пишу простую программу. В нем только один класс. Есть закрытый член 'char * number' и две функции (их будет больше, но сначала они должны работать правильно :)).

Первый должен скопировать переменную 'source' в 'number' (и я полагаю, что где-то здесь проблема):

LongNumber::LongNumber(const char * source ){
        int digits = strlen(source);

        char* number = new char[digits+1];
        strcpy( number, source );
        //  cout<<number<<endl; - if the line is uncommented,
        //  the output is correct and there isn't a problem

}

И функция печати:

void LongNumber::print(){
    cout<<number<<endl;
    // when I try to print with the same line of code here..it crashes
}

Конечно, я что-то упускаю ... но что?

(Поскольку это мой первый пост ... как вы думаете, исправлены ли теги .. как бы вы пометили пост?)

Заранее спасибо:)

Ответы [ 4 ]

6 голосов
/ 28 июня 2009

Ваш массив чисел char * выйдет из области видимости при выходе из конструктора. Когда вы достигнете функции print (), так как программа больше не имеет доступа к памяти, на которую изначально указывает * число, произойдет сбой (т.е. ошибка сегментации). Чтобы решить эту проблему, сделайте это вместо:

class LongNumber
{
     char *number;
     LongNumber(const char *source);
     ~LongNumber();
     void print();
};

LongNumber::LongNumber(const char * source ){
        int digits = strlen(source);

        number = new char[digits+1];
        strcpy( number, source );    
}

void LongNumber::print(){
    cout<<number<<endl;
}

Не забудьте сделать следующее:

LongNumber::~LongNumber()
{
    delete [] number;    // to avoid memory leaks
}

Я бы также настоятельно рекомендовал использовать STL :: string вместо char * для вашей * числовой переменной, так как вам не придется самостоятельно управлять служебной памятью, а копирование строки также будет проще.

5 голосов
/ 28 июня 2009

В конструкторе LongNumber вы объявляете новую локальную переменную с именем number и инициализируете ее новым массивом char:

char* number = new char[digits+1];

Вместо этого вы должны опустить char*, чтобы он не выглядел как объявление новой переменной и использовал переменную-член объекта:

number = new char[digits+1];

При текущем коде переменная-член number никогда не инициализируется, и использование ее позже в print приводит к ошибке.

1 голос
/ 28 июня 2009

Мне кажется, что вы объявили число в качестве локальной переменной. Если вы хотите иметь возможность вызывать его снова в другой функции, вы должны объявить его в определении класса ... вот так:

class LongNumber{
public:
        int digits;
        char* number;
        LongNumber(const char * source );
        void print();
}

LongNumber::LongNumber(const char * source ){
        digits = strlen(source);
        number = new char[digits+1];
        strcpy( number, source );
        //  cout<<number<<endl; - if the line is uncommented,
        //  the output is correct and there isn't a problem
}

void LongNumber::print(){
    cout<<number<<endl;
    // when I try to print with the same line of code here..it crashes
}

Надеюсь, это поможет !!!

1 голос
/ 28 июня 2009

Ваша проблема в конструкторе:

LongNumber::LongNumber(const char * source )
{
  ...
  // you are declaring a new local variable called `number` here
  char* number = new char[digits+1];
  strcpy( number, source );
  ...
}

Вы не копируете в переменную-член класса с именем number, вы объявляете новую локальную переменную в теле конструктора и используете ее. Переменная члена класса не используется и, вероятно, не определена. Для элемента указателя это означает, что значением может быть любое недопустимое значение - тогда, когда вы вызываете print:

void LongNumber::print()
{
  cout<<number<<endl;
  // when I try to print with the same line of code here..it crashes
}

number, который вы здесь используете, является переменной члена класса, которая, как мы сказали, не определена. В этом случае вызов cout завершится сбоем, поскольку он попытается использовать этот неверный указатель.

Исправление состоит в том, чтобы заставить конструктор использовать правильную переменную члена класса:

LongNumber::LongNumber(const char * source )
{
  ...
  // use the class member variable `number` here
  number = new char[digits+1];
  strcpy( number, source );
  ...
}
...