Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.09.2009, 21:11   #1
oxygen90
Новичок
Джуниор
 
Регистрация: 14.09.2009
Сообщений: 2
По умолчанию Проблема выделения динамической памяти в С++

Добрый вечер, уважаемые специалисты. Возникла проблема с выделением динамической памяти под строку в С++. Это учебный пример, взят из книги Х. М. Дейтла "Как программировать на С++" и должен быть, по идее, гарантированно правильным. Сам пересмотрел весь код, но ошибок не нашёл. Гуглил, но ничего внятного опять же не нашёл. Подозреваю, что проблема не в коде, а в Visual Studio 2008, в которой этот код компилировался и выполнялся. Привожу последовательно 3 файла (заголовочный с классом, реализацию, и тест этого класса) ничего не упрощая и не изменяя. Благодарю за внимание.

Код:
// Employee.h
// Определение класса Employee.
#ifndef EMPLOYEE_H
#define EMPLOYEE_H

class Employee
{
public:
	Employee (const char * const, const char * const); // конструктор
	~Employee(); // destructor
	const char *getFirstName() const; // возвратить имя
	const char *getLastName() const; // возвратить фамилию

	// статическая элемент-функция
	static int getCount(); // возвратить число созданных объектов
private:
	char *firstName;
	char *lastName;

	// static data
	static int count; // число созданных объектов
}; // конец класса Employee

#endif


// Employee.cpp
// Определение элемент-функций класса Employee.
#include "stdafx.h"
#include <iostream>
using std::cout;
using std::endl;

#include <cstring> // прототипы strlen и strncpy
using std::strlen;
using std::strncpy;

#include "Employee.h" // определение класса Employee

// определить и инициализировать статический элемент данных
int Employee::count = 0;

// определить статическую элемент-функцию, возвращающую число
// созданных объектов Employee (объявлена static в Employee.h)
int Employee::getCount()
{
	return count;
} // конец статической функции getCount

// конструктор динамически выделяет память для имени и фамилии
// и вызывает strcpy для копирования имени и фамилии в объект
Employee::Employee(const char *const first, const char *const last)
{
	int a = strlen(first);
	firstName = new char[a+1];
	strcpy (lastName, first);

	lastName = new char [strlen(last) + 1];
	strcpy (lastName, last);

	count++; // увеличить статический счётчик служащих

	cout << "Employee constructor for " << firstName << ' ' << lastName << " called." << endl;
} // конец конструктора Employee

// деструктор освобождает динамически выделенную память
Employee::~Employee()
{
	cout << "~Employee() called for " << firstName << ' ' << lastName << endl;

	delete [] firstName; // освободить память
	delete [] lastName; // освободить память

	count--; // уменьшить статический счётчик служащих
} // конец деструктора ~Employee

// возвратить имя служащего
const char *Employee::getFirstName() const
{
	// const перед возвращаемым типом не даёт клиенту модифицировать
	// закрытые данные; клиент должен скопировать строку, прежде чем
	// деструктор освободит память и указатель станет неопределённым
	return firstName;
} // конец функции getFirstName

// возвратить фамилию служащего
const char *Employee::getLastName() const
{
	// const перед возвращаемым типом не даёт клиенту модифицировать
	// закрытые данные; клиент должен скопировать строку, прежде чем
	// деструктор освободит память и указатель станет неопределённым
	return lastName;
} // конец функции getLastName


// Сотрудники_2.cpp : Defines the entry point for the console application.
// Тестер для класса Employee.

#include "stdafx.h"
#include <iostream>
using std::cout;
using std::endl;

#include "Employee.h" // определение класса Employee

int _tmain(int argc, _TCHAR* argv[])
{
	// использовать имя класса и операцию разрешения области
	// действия, чтобы обратиться к статическому элементу getCount
	cout << "Number of employee before creation of any objects is "
		<< Employee::getCount() << endl; // использовать имя класса

	// использовать new для динамического создания двух Employee
	// операция new вызывает также конструктор объекта
	Employee *e1Ptr = new Employee ("Susan", "Baker");
	Employee *e2Ptr = new Employee ("Robert", "Jones");

	// вызвать getCount для первого объекта Employee
	cout << "Number of employees after objects are instantiated is "
		<< e1Ptr->getCount();

	cout << "\n\nEmployee 1: " << e1Ptr->getFirstName() << " " << e1Ptr->getLastName()
		<< "\nEmployee 2: " << e2Ptr->getFirstName()
		<< " " << e2Ptr->getLastName() << "\n\n";

	delete e1Ptr; // освободить память
	e1Ptr = 0; // отсоединить указатель от области свободной памяти
	delete e2Ptr; // освободить память
	e2Ptr = 0; // отсоединить указатель от области свободной памяти

	// объектов нет, поэтому для вызова статической функции getCount
	// используется имя класса и операция разрешения области действия
	cout << "Number of employees after pbjects are deleted is "
		<< Employee::getCount() << endl;
	return 0;
} // конец main
Ставил брейк-поинты. Вылетает при выполнении конструктора вот здесь.

firstName = new char[a+1];

Последний раз редактировалось Stilet; 15.09.2009 в 08:50.
oxygen90 вне форума Ответить с цитированием
Старый 14.09.2009, 21:19   #2
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Код:
Employee::Employee(const char *const first, const char *const last)
{
int a = strlen(first);
firstName = new char[a+1];
strcpy (lastName, first);
тут, в ф-цию strcpy в качестве первого параметра нужно указывать firstName, ведь Вы под неё только что выделили память
lastName на данный момент неправильный указатель

Последний раз редактировалось netrino; 14.09.2009 в 21:52.
netrino вне форума Ответить с цитированием
Старый 14.09.2009, 21:37   #3
mMAg
Форумчанин
 
Аватар для mMAg
 
Регистрация: 11.08.2009
Сообщений: 433
По умолчанию

Цитата:
Это учебный пример, взят из книги Х. М. Дейтла "Как программировать на С++" и должен быть, по идее, гарантированно правильным
Ох, неправда. Некоторые авторы в своих книгах даже специально делают ошибки, чтобы читатель не тупо копипастил, а еще и понимал, что же он копипастит.
mMAg вне форума Ответить с цитированием
Старый 14.09.2009, 21:47   #4
oxygen90
Новичок
Джуниор
 
Регистрация: 14.09.2009
Сообщений: 2
По умолчанию

Ой! Спасибо вам. Несколько раз просматривал и не заметил. Простите за беспокойство и за напрасно созданную тему.
oxygen90 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Распределение динамической памяти в Borland C++ 3.1! CePryH Помощь студентам 3 15.06.2009 23:59
Динамическая выделения памяти megavolt91 Общие вопросы C/C++ 1 25.05.2009 21:05
Проблемы с выделением динамической памяти malloc (recalloc) slips Общие вопросы C/C++ 6 29.04.2009 19:27
Вопрос по структурам и динамической памяти. ROD Общие вопросы C/C++ 4 12.04.2009 18:20
Вставка по динамической памяти в Delphi Schakhmaev Помощь студентам 1 24.06.2008 01:27