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

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

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

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

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

Закрытая тема
Ваша тема закрыта, почему это могло произойти? Возможно,
Нет наработок или кода, если нужно готовое решение - создайте тему в разделе Фриланс и оплатите работу.
Название темы включает слова - "Помогите", "Нужна помощь", "Срочно", "Пожалуйста".
Название темы слишком короткое или не отражает сути вашего вопроса.
Тема исчерпала себя, помните, один вопрос - одна тема
Прочитайте правила и заново правильно создайте тему.
 
Опции темы Поиск в этой теме
Старый 15.05.2010, 16:49   #1
eraserhp
Пользователь
 
Регистрация: 15.05.2010
Сообщений: 24
По умолчанию Странное поведение realloc

Доброго всем времени суток.

Необходимо организовать двумерный динамический массив.

Код:

Код:
double **Matrix;

	Matrix = (double**)calloc(2048, sizeof(double*));
	for (int i = 0; i < 2048; i++)
	{
		Matrix[i] = (double*)calloc(2048, sizeof(double));
	}

	MatrixSize = 2048;

	MapFind->MapSelect->ClearAll();

	MapFind->Active = false;
	MapFind->FindPoint=false;
	MapFind->MapSelect->MapSites[-1] = false;
	MapFind->MapSelect->MapSites[NetNumber + 1] = true;
	MapFind->MapSelect->SiteNumber = NetNumber + 1;
	MapFind->MapSelect->KeyObject[""] = false;
	MapFind->MapSelect->KeyObject["L0000005557"]= true;
	MapFind->Active= true;

	MapObj->Style = OS_NOVIEW;
	MapObj1->Style = OS_NOVIEW;
	MapFind->First();

	while(!MapFind->Eof)
		{
			int StartPoint = 0, EndPoint = 0;
			for(int i = 0; i < MapFind->MapObj->Semantic->SemanticCount; ++i)
			{
				if(MapFind->MapObj->Semantic->SemanticCode[i] == 32813)
				{
					StartPoint = StrToInt(MapFind->MapObj->Semantic->SemanticValue[i]);
					if(!FirstNode)
						FirstNode = StartPoint;
				}
				else if(MapFind->MapObj->Semantic->SemanticCode[i] == 32814)
					EndPoint = StrToInt(MapFind->MapObj->Semantic->SemanticValue[i]);
			}

			while(StartPoint - FirstNode > MatrixSize - 1
					|| EndPoint - FirstNode > MatrixSize - 1)
			{
				MatrixSize *= 2;
				Matrix = (double**)realloc((void*)Matrix, MatrixSize * sizeof(double*));
				for (int i = 0; i < MatrixSize; i++)
				{
					Flag = false;

					try
					{
						Matrix[i] = (double*)realloc((void*)Matrix[i], MatrixSize * sizeof(double));
					}
					catch(...)
					{
						ShowMessage(i);
					}
				}
			}
			try
			{
			     Matrix[StartPoint - FirstNode][EndPoint - FirstNode] = MapFind->MapObj->Length;
			     Matrix[EndPoint - FirstNode][StartPoint - FirstNode] = MapFind->MapObj->Length;
			}
			catch(...)
			{
			     ShowMessage("Начальная точка ребра: " + IntToStr(StartPoint - FirstNode));
			     ShowMessage("Конечная точка ребра: " + IntToStr(EndPoint - FirstNode));
			     ShowMessage("Номер ребра: " + IntToStr(MapFind->MapObj->Key));
			     ShowMessage("Длина ребра: " + FloatToStr(MapFind->MapObj->Length));
			}
			if(StartPoint - FirstNode < 0 || EndPoint - FirstNode < 0)
			{
			     ShowMessage("Начальная точка ребра: " + IntToStr(StartPoint - FirstNode));
			     ShowMessage("Конечная точка ребра: " + IntToStr(EndPoint - FirstNode));
			     ShowMessage("Номер ребра: " + IntToStr(MapFind->MapObj->Key));
			     ShowMessage("Длина ребра: " + FloatToStr(MapFind->MapObj->Length));
			}

			MapFind->Next();
		}
	ShowMessage(MatrixSize);
При перераспределении памяти в выделенном месте только при i = 2058, вылетает Access violation in module BORLNDMM.dll

Не выделяется память только под 2058 строку.

Плиз хелп гуру)))
eraserhp вне форума
Старый 15.05.2010, 20:25   #2
Carbon
JAVA BEAN
Участник клуба
 
Аватар для Carbon
 
Регистрация: 22.04.2007
Сообщений: 1,329
По умолчанию

realloc будет вылетать, если первый параметр - невалидный указатель.
Carbon вне форума
Старый 15.05.2010, 23:33   #3
eraserhp
Пользователь
 
Регистрация: 15.05.2010
Сообщений: 24
По умолчанию

В смысле невалидный???

Вопрос тогда такой:

после выделения памяти через calloc доступно 2048 ячеек (0 - 2047), почему в дебагере ячейки [2048] - [2057] и [2060] и т.д. есть NULL, а вот [2058] и [2059] уже имеют адрес, правда обратиться по нему нельзя???
eraserhp вне форума
Старый 15.05.2010, 23:34   #4
eraserhp
Пользователь
 
Регистрация: 15.05.2010
Сообщений: 24
По умолчанию

Как может быть для всех строк нормальный указатель, а только для одной нет??? Причем всегда для одной и той же???
eraserhp вне форума
Старый 16.05.2010, 18:34   #5
Carbon
JAVA BEAN
Участник клуба
 
Аватар для Carbon
 
Регистрация: 22.04.2007
Сообщений: 1,329
По умолчанию

Цитата:
Сообщение от eraserhp Посмотреть сообщение
В смысле невалидный???
В прямом. Сначала выделяется память под 2048 элементов вот так:
Код:
for (int i = 0; i < 2048; i++)
{
	Matrix[i] = (double*)calloc(2048, sizeof(double));
}
И тут всё нормально. Но затем понадобилось удвоить размерность:
Код:
MatrixSize *= 2;
Matrix = (double**)realloc((void*)Matrix, MatrixSize * sizeof(double*));
Оно удвоилось. Но значения от 2048 до 4095 заполнились мусором, потому что realloc не обнуляет данные, под которые выделяет память.
И всё было бы нормально, если бы дальше к этому мусору не применялась realloc:
Код:
Matrix[i] = (double*)realloc((void*)Matrix[i], MatrixSize * sizeof(double));
Как я уже сказал, realloc первым аргументом должен принимать либо валидный указатель, либо 0. Во втором случае его действие аналогично malloc, в первом же он сначала выделяет память, затем копирует участок памяти из старой области в новую, затем удаляет старую. Поэтому там должен быть валидный указатель. Но здесь значения от 2048 до 4095 заполнены мусором и происходит попытка удаления совершенно левого указателя.

ЗЫ И не нужно дебагить мусор. Там может быть и совершенно нормальный 0 и валидный указатель (правда на совершенно другое место) и всё что угодно.
Carbon вне форума
Старый 16.05.2010, 20:03   #6
eraserhp
Пользователь
 
Регистрация: 15.05.2010
Сообщений: 24
По умолчанию

Так указатель то валидный получается, просто в нем храниться мусор, а память то выделена!

Как можно решить данную проблему???
eraserhp вне форума
Старый 17.05.2010, 00:01   #7
Carbon
JAVA BEAN
Участник клуба
 
Аватар для Carbon
 
Регистрация: 22.04.2007
Сообщений: 1,329
По умолчанию

Цитата:
Сообщение от eraserhp Посмотреть сообщение
Так указатель то валидный получается, просто в нем храниться мусор, а память то выделена!
Matrix - валидный. Я не спорю.
Matrix[i] от 2048 невалидны, а к ним применяется realloc.

Можно для первой половины вызывать realloc, для второй malloc или calloc.
Можно обнулить вторую половину массива.
Carbon вне форума
Старый 17.05.2010, 09:52   #8
eraserhp
Пользователь
 
Регистрация: 15.05.2010
Сообщений: 24
По умолчанию

Проблема решена, но как то вроде раньше все нормально было с realloc. Точно уже использовал такое вот динамическое распределение памяти, проблем не возникало. Раньше юзал VS и Borland 6, ща Borland 2009. Возможно из-за платформ.... Спасибо огромное. Буду иметь ввиду в будущем)))
eraserhp вне форума
Закрытая тема


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

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Странное поведение gets alex_alpha Общие вопросы C/C++ 3 27.03.2010 18:21
Странное поведение null Vitalyk JavaScript, Ajax 6 13.02.2010 15:22
Странное поведение TTreeView mutabor Компоненты Delphi 1 01.05.2009 05:17
Странное поведение базы yulia БД в Delphi 7 22.04.2009 07:15