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

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

Вернуться   Форум программистов > C/C++ программирование > Visual C++
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 13.12.2010, 22:14   #1
Zhigool'
Пользователь
 
Регистрация: 11.07.2010
Сообщений: 29
По умолчанию Динамический массив как закрытый член класса

Здравствуйте Господа и Дамы!
У меня задачка: необходимо создать программу, которая создаёт массив объектов. У каждого объекта есть свой массив произвольного размера и содержания. Доступ к этому массиву осуществляется через открытые члены-функции.
Вот что я наваял:
Код:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;

class Mass
{
	float *mas;
	unsigned short k;
public:
	float *mass(unsigned short i)
	{
		float *mas = new float [i];
		for(unsigned short j=0;j<i;j++)
		{
			mas[j]=j;
		}
		k=i;
	return mas;
	}
	void GetMass()
	{
		for(unsigned short i=0; i<k;i++)
		{
			cout<<*mas<<"  ";
			*mas++;
		}
		cout<<"\n"<<endl;
		delete [] mas;
	}
};
void _tmain()
{
	Mass s;
	unsigned short i=10;
	s.mass(i);
	s.GetMass();
	_getch();
}
Скомпилировал, запустил и выдалась ошибка - "Необработанное исключение в "0x00fe16f3" в "Динамический массив.exe": 0xC0000005: Нарушение прав доступа при чтении "0xcccccccc"."
Поправьте если я не прав. Функцией "float *mass()" я создаю массив и передаю указатель на него в закрытый "float *mas". Но когда "float *mass()" заканчивает своё выполнение массив уничтожается, а указатель сохранен в "float *mas", который указывает на первый элемент уже несуществующего массива. Так?
Но тогда ка же решить эту задачу?
Zhigool' вне форума Ответить с цитированием
Старый 13.12.2010, 22:22   #2
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

Код:
	void GetMass()
	{
		for(unsigned short i=0; i<k;i++)
		{
			cout<<*mas<<"  ";
			*mas++;
		}
		cout<<"\n"<<endl;
		delete [] mas;
	}
потерял указатель
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 13.12.2010, 22:28   #3
Zhigool'
Пользователь
 
Регистрация: 11.07.2010
Сообщений: 29
По умолчанию

ммм...
Код:
delete [] *mas;
так? но visual studio ругается...
Zhigool' вне форума Ответить с цитированием
Старый 13.12.2010, 22:29   #4
ACE Valery
Сама себе режиссер
Старожил
 
Аватар для ACE Valery
 
Регистрация: 27.04.2007
Сообщений: 3,365
По умолчанию

Да тут помимо потери указателя...
В следующем куске кода вы почему-то переобъявляете свой массив локально.
Код:
float *mass(unsigned short i)
	{
		float *mas = new float [i];
		for(unsigned short j=0;j<i;j++)
		{
			mas[j]=j;
		}
		k=i;
	return mas;
	}
Поэтому записываются данные в локальный mas, а свойство вашего класса остается без изменений. Исправьте строчку
Код:
float *mas = new float [i];
на
Код:
mas = new float [i];
Во-вторых, что это за ужас?
Код:
void GetMass()
	{
		for(unsigned short i=0; i<k;i++)
		{
			cout<<*mas<<"  ";
			*mas++;
		}
		cout<<"\n"<<endl;
		delete [] mas;
	}
Вы хотите вывести массив на экран? Вот
Код:
void GetMass()
	{
		for(unsigned short i=0; i<k;i++)
		{
			cout<<mas[i]<<"  ";
			
		}
		cout<<"\n"<<endl;
		delete [] mas;
	}
Что за ухищрения с передвиганием указателя? Вы же потом удаляете массив как? По указателю, который уже давно не показывает на начало массива.
Если я вас напрягаю или раздражаю, вы всегда можете забиться в угол и поплакать

Последний раз редактировалось ACE Valery; 13.12.2010 в 22:31.
ACE Valery вне форума Ответить с цитированием
Старый 13.12.2010, 22:44   #5
Zhigool'
Пользователь
 
Регистрация: 11.07.2010
Сообщений: 29
По умолчанию

2 ACE Valery
Я только начал программировать. Спасибо Вам за помощь! Заработало.
Интересно, что вот так:
Код:
	
void GetMass()
   {
	for(unsigned short i=0; i<k;i++)
        {
	      cout<<*mas<<"  ";
	      *mas++;
	}
	cout<<"\n"<<endl;
	delete [] mas;
}
Работает! )
Zhigool' вне форума Ответить с цитированием
Старый 13.12.2010, 22:49   #6
ACE Valery
Сама себе режиссер
Старожил
 
Аватар для ACE Valery
 
Регистрация: 27.04.2007
Сообщений: 3,365
По умолчанию

Что, правда работает? И не вываливается после вывода массива? Странно-странно...
Если я вас напрягаю или раздражаю, вы всегда можете забиться в угол и поплакать
ACE Valery вне форума Ответить с цитированием
Старый 14.12.2010, 00:03   #7
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

может и не вываливается, но утечки должны быть.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 14.12.2010, 04:09   #8
Zhigool'
Пользователь
 
Регистрация: 11.07.2010
Сообщений: 29
По умолчанию

В развитии темы:
Код:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <time.h>
using namespace std;

class Mass
{
	float **mas;
	unsigned short m,n;
public:
	float **mass(unsigned short a,unsigned short c)
	{
		float **mas = new float*[a];
		for(unsigned short j=0;j<a;j++)
		{
			mas[j]=new float[c];
		}
		for(unsigned short i=0;i<a;i++)
		{
			for(unsigned short j=0;j<c;j++)
			{
				mas[i][j]=0;
			}
		}
		m=a;n=c;
		return mas;
	}
	void SetMass()
	{
		srand(clock());
		for(unsigned short i=0;i<m;i++)
		{
			for(unsigned short j=0;j<n;j++)
			{
				float g=(rand()%10000);
				mas[i][j]=(g/10000)*2;
			}
		}
	}
	void GetMass()
	{
		for(unsigned short i=0;i<m;i++)
		{
			for(unsigned short j=0;j<n;j++)
			{
			cout<<mas[i][j]<<" ";
			}
		}
		cout<<"\n"<<endl;
	}
	void DelMass()
	{
		delete[]mas;
	}
};
void _tmain()
{
	clock_t time;
	time = clock();
	Mass s[2];
	unsigned short a=10,c=10;
	for(unsigned short p=0; p<2;p++)
	{
		s[p].mass(a,c);
	}
	for(unsigned short p=0; p<2;p++)
	{
		s[p].SetMass();
		s[p].GetMass();
	}
	
	for(unsigned short p=0; p<2;p++)
	{
		s[p].DelMass();
	}
	time=clock()-time;
	cout<<(double)time/CLOCKS_PER_SEC;
	_getch();
}
Не работает и выдает ошибку:"Необработанное исключение в "0x01321121" в "Динамический массив.exe": 0xC0000005: Нарушение прав доступа при записи "0x42bc2583"." Что не так?
Zhigool' вне форума Ответить с цитированием
Старый 14.12.2010, 10:55   #9
ACE Valery
Сама себе режиссер
Старожил
 
Аватар для ACE Valery
 
Регистрация: 27.04.2007
Сообщений: 3,365
По умолчанию

Мдяяя... Перечитайте сообщение №4. Вы снова в функции
float **mass(unsigned short a,unsigned short c)
объявляете локальную переменную mas, в которую и записываются данные.
Если я вас напрягаю или раздражаю, вы всегда можете забиться в угол и поплакать
ACE Valery вне форума Ответить с цитированием
Старый 15.12.2010, 11:35   #10
Zhigool'
Пользователь
 
Регистрация: 11.07.2010
Сообщений: 29
По умолчанию

Ещё проблемка возникла. При создании большого количества объектов, в которых содержится двумерный массив с большим количеством элементов, происходит переполнение стека. Как можно избавиться от ограничений. Планирую использовать все 8ГБ оперативы.
Код:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <time.h>
using namespace std;
#define KOLVONS 1000 //количество объектов класса
class Mass
{
	float **mas;
	int m,n;
public:
	float **mass(int a,int c) //создание массива
	{
		mas=new float*[a];
		for(int j=0;j<a;j++)
		{
			mas[j]=new float[c];
		}
		for(int i=0;i<a;i++)
		{
			for(int j=0;j<c;j++)
			{
				mas[i][j]=0;
			}
		}
		m=a;n=c;
		srand(clock());
		return mas;
	} 
	void SetMass() //Установка элементов динамического массива в случайное значение
	{
		srand(clock());
		for(int i=0;i<m;i++)
		{
			for(int j=0;j<n;j++)
			{
				double g=(rand()%10000);
				mas[i][j]=(g/10000)*2;
			}
		}
	}
	void GetMass() //Вывод результатов работы проги для её контроля
	{
		for(int i=0;i<m;i++)
		{
			for(int j=0;j<n;j++)
			{
			cout<<mas[i][j]<<" ";
			}
		}
		cout<<"\n"<<endl;
	}
	void DelMass() //удаление динамического массива
	{
		for(int i=0;i<n;i++)
		{
			delete[]mas[i];
		}
		delete[]mas;
	}
};
void _tmain()
{
	clock_t time;
	time = clock();
	Mass s[KOLVONS];
	int a=100,c=100;
	for(int p=0; p<KOLVONS;p++)
	{
		s[p].mass(a,c);
	}
	for(int p=0; p<KOLVONS;p++)
	{
		s[p].SetMass();
	}
	for(int p=0; p<KOLVONS;p++)
	{
		s[p].DelMass();
	}
	time=clock()-time;
	cout<<(double)time/CLOCKS_PER_SEC;
	_getch();
}
Zhigool' вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
вектор как закрытый член класса, как изменять его значения? Zhigool' Общие вопросы C/C++ 3 08.08.2010 23:19
2-мерный динамический массив экземпляров класса. С++ Парсифаль Общие вопросы C/C++ 1 29.12.2009 14:35
Функция - член класса Syltan Общие вопросы C/C++ 9 06.10.2009 23:44
Указатеть на функция-член класса BioS Общие вопросы C/C++ 6 29.09.2009 00:04
Как изменить статический приватный член класса?? 3dgraph Помощь студентам 2 07.05.2009 20:06