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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 20.03.2012, 13:08   #1
Elloriane
Пользователь
 
Регистрация: 19.02.2012
Сообщений: 60
Восклицание Проблема с _gcvt (возможно), задача не на пару минут

Сегодня столкнулся с удивительной для меня проблемой..
Я, написал программу и по шагам, отдебажив и перепробовав все варианты, с облегчением вздохнул - всё работает, но не тут-то было.
Оказывается все работает, если (к примеру, поставить breakpoint на конец главной функции, а именно на return 0, он все верно, без ошибок(!) выполняет(любое другое место - все верно))

Но, когда я запускаю программу через Ctrl + f5, меня тут же "критует", выбрасывает с необработанным исключением. И больше никакой информации. Я даже проверить место, где ошибка не могу
(я только начинающий, поэтому заглянуть в скомпилинный код и так далее - не вариант, не разберусь)

Вроде как через comment/uncomment я выявил виновника:
Код:
_gcvt(firstNumD, dotPlace + oneMoreDot, numberString);
,
для ясности приведу всю функцию полностью
(КОД ЧИТАТЬ НЕ ОБЯЗАТЕЛНО, Т.К. ОЧЕНЬ ВЕЛИК)
я его привел, чтобы было ясно какие типы в аргументах и к чему представлена сея функция

(на вход идет строка, в польской нотации)
Код:
double countPolsString(const char *fileString)
{
	//struct
	//{
	//	char * symb;
	//	double * num;
	//	int sizeOfC;
	//	int SizeOfD;
	//}mass;
	char  *copyString = NULL, *tempString = NULL, * firstNumberC = NULL, * secondNumberC = NULL, *endCopyString = NULL, *numberString = NULL, *space = NULL;
	int i = 0, j = 0, r = 0, size = sizeof(char), flag = 0, jmem = 0, dotPlace = 0, firstBorder = 0, secondBorder = 0, oneMoreDot = 0;
	double firstNumD = 0, secondNumD = 0, tempSecondNumber;
	space = malloc(sizeof(char));
	space[0] = ' ';
	space[1] = 0;
	while(fileString[i] != 0)
	{
		tempString = realloc(copyString, size);
		if (tempString != NULL)
			copyString = tempString;
		copyString[i] = fileString[i];
		i++;
		size += sizeof(char);
	}
	copyString[i] = 0;
	i = 0;
	while (copyString[i] != 0)
	{
		if (((copyString[i] == '+')||(copyString[i] == '-')||(copyString[i] == '*')||(copyString[i] == '/')||(copyString[i] == '^'))&& \
			((copyString[i + 1] == ' ')||(copyString[i + 1] == 0)))
		{
			flag = 0;
			j = i;
			while (flag != 2)
			{
				//создаю 2 char* строки, куда записываю пару чисел.
			}
			if (flag == 2)
			{
				flag = 0;
				switch(copyString[i])
				{
				case '-':
						firstNumD -= secondNumD;
						break;
				case '+':
						firstNumD += secondNumD;
						break;
				case '/':
						if (secondNumD == 0)
						{
							printf ("ERROR: division by zero");
						}
						else
							firstNumD /= secondNumD;
						break;
				case '^':
						tempSecondNumber = secondNumD;
						while (floor(tempSecondNumber) != tempSecondNumber)
							tempSecondNumber *= 10;
						if ((firstNumD < 0)&&(((int)tempSecondNumber) % 2 == 0))
							printf ("ERROR");
						else
						firstNumD = pow (firstNumD, secondNumD);
						break;
				case '*':
						firstNumD *= secondNumD;
						break;
				}
				if (copyString[i + 1] != 0)
				{endCopyString = NULL;
				dotPlace = 0;
				oneMoreDot = 0;
				if (firstNumD >= 0)
					tempSecondNumber = firstNumD;
				else
					tempSecondNumber = -firstNumD;
				//we search for the amaount of the numbers before the dot
				while (tempSecondNumber >= 1)
				{
					oneMoreDot++;
					tempSecondNumber /= 10;
				}
				tempSecondNumber = firstNumD;
				//we search for the amaount of the numbers after the dot
				while (floor(tempSecondNumber) != tempSecondNumber)
				{
					dotPlace++;
					tempSecondNumber *= 10;
				}
				//make a double to string
				numberString = malloc(sizeof(char)*i);
				_gcvt(firstNumD, dotPlace + oneMoreDot, numberString);
				//create the end of the string
				firstBorder = i;
				secondBorder = 0;
				size = sizeof(char);
				while (copyString[firstBorder] != 0)
				{
					if (((copyString[firstBorder] == '*')||(copyString[firstBorder] == '/')||(copyString[firstBorder] == '+')||(copyString[firstBorder] == '-')||(copyString[firstBorder] == '^'))&&(firstBorder == i))
						firstBorder++;
					else
					{
						tempString = realloc(endCopyString, size);
						if (tempString != NULL)
							endCopyString = tempString;
						endCopyString[secondBorder++] = copyString[firstBorder++];
						size += sizeof(char);
					}
				}
				//cnnecting strings - beggining - spase - number - ending
				if (j > 0)
				{
					copyString[j - 1] = 0;
					strcat(copyString, space);
				}
				else
					copyString[j] = 0;
				strcat(copyString, numberString);
				strcat(copyString, endCopyString);
				jmem = 0;
				//cleaning the end
				while ((copyString[jmem] == '+')||(copyString[jmem] == '-')||(copyString[jmem] == '/')||(copyString[jmem] == '*')|| \
					(copyString[jmem] == '^')||(copyString[jmem] == ' ')||(copyString[jmem] == '.')||((copyString[jmem] >= '0')&&(copyString[jmem] <= '9')))
					jmem++;
				copyString[jmem] = 0;
				i = 0;
				}
			}
		}
		i++;
	}
	return (firstNumD);
}
Проверил - прототип указан верно, обращаюсь верно, возвращаемое значение идет в double
Я просто в смятении, прошу помощи.

Последний раз редактировалось Elloriane; 20.03.2012 в 13:12.
Elloriane вне форума Ответить с цитированием
Старый 20.03.2012, 13:09   #2
Elloriane
Пользователь
 
Регистрация: 19.02.2012
Сообщений: 60
По умолчанию

Текст был слишком длинный.
вот создание двух динамических строк
Код:
if ((flag == 0)&&(copyString[j - 2] == ' '))
				{
					size = sizeof(char);
					tempString = NULL;
					secondNumberC = NULL;
					firstNumberC = NULL;
					for (r = j; r <= i - 1; r++)
					{
					tempString = realloc(secondNumberC, size);
					if (tempString != NULL)
						secondNumberC = tempString;
					secondNumberC[r - j] = copyString[r - 1];
					size += sizeof(char);
					}
					secondNumberC[r - j--] = 0;
					secondNumD = atof(secondNumberC);
					flag++;
					jmem = j;
				}
				if ((flag == 1)&&((copyString[j - 2] == ' ')||(j == 1)))
				{
					size = sizeof(char);
					for (r = j; r <= jmem - 1; r++)
					{
					tempString = realloc(firstNumberC, size);
					if (tempString != NULL)
						firstNumberC = tempString;
					firstNumberC[r - j] = copyString[r - 1];
					size += sizeof(char);
					}
					firstNumberC[r - j] = 0;
					firstNumD = atof(firstNumberC);
					flag++;
				}
				j--;
Elloriane вне форума Ответить с цитированием
Старый 20.03.2012, 13:27   #3
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию

Бросилось в глаза из самого начала:
Код:
	space = malloc(sizeof(char));
	space[0] = ' ';
	space[1] = 0;
Вы выделяете место только под один символ, а используете сразу два. Необходимо выделить место под оба.
Также выделяя память, вы ее не освобождаете через free.
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 20.03.2012, 13:29   #4
Elloriane
Пользователь
 
Регистрация: 19.02.2012
Сообщений: 60
По умолчанию

забыл про ошибку с памятью, в процессе исправления, отпишусь как доделаю

только небольшой вопрос : space[1] = 0
это же несимвол - я стираю возможный мусор после " "?

Хм, забавно, но как раз во время вызова функции free() для 4 из 5 динамических строк вылезают различного рода ошибки, разбираюсь

И ошибка рода (Heap Corruption Detected)
Я правильно понял, что программа узнала о том что я вылжу за пределы массива уже после того как я это сделал и обнулил строки?

но что любопытно появляется ошибка совершенно другого рода : повреждение кучи при очистке stringcopy (ошибка подобного рода (только без дополнительных данных для диагностики)
http://www.cyberforum.ru/cpp-beginners/thread54226.html)

тогда у меня вопрос, я вообще могу так делать:?
Код:
strcat(copyString, numberString);
strcat(copyString, endCopyString);
где
Код:
numberString = malloc(sizeof(char)*i); //больше чем надо!
_gcvt(firstNumD, dotPlace + oneMoreDot, numberString);
и
Код:
tempString = realloc(endCopyString, size); // обыкновенный relloc!
if (tempString != NULL)
endCopyString = tempString;
endCopyString[secondBorder++] = copyString[firstBorder++];
size += sizeof(char);

Последний раз редактировалось ACE Valery; 20.03.2012 в 20:36.
Elloriane вне форума Ответить с цитированием
Старый 20.03.2012, 14:03   #5
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию

Elloriane, здесь вам все-таки не твиттер. Либо пишите все сразу в одном посте, либо используйте кнопку редактирования сообщения в нижнем правом углу.
Что касается нуля - это хоть и не символ в привычном понимании, но компилятору, строго говоря, вообще пофиг, что все эти буковки являются символами. Короче говоря, ноль - это терминирующий символ, он является элементом данных и нельзя про него забывать. То, что вы поставили его в конец строки - не заставляет что-то там стереть (произвести в момент присвоения какие-то активные действия), а всего лишь будет указывать, что на этом символе необходимо прекращать чтение из памяти, и дальше будет уже что-то не относящееся к данной текстовой строке.
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 20.03.2012, 14:14   #6
Elloriane
Пользователь
 
Регистрация: 19.02.2012
Сообщений: 60
По умолчанию

Извините за такой поток, если Вы подскажете, как удалять сообщения - я подправлю.
Про символ - понял, исправил. Ошибка при free(copyString) осталась, как я понимаю - она (динамическая строка) проблема, по которой ctrl+f5 не работает?
т.к. вроде он выявляет то, что я вылажу за границу после выполнения функции
Elloriane вне форума Ответить с цитированием
Старый 20.03.2012, 20:37   #7
ACE Valery
Сама себе режиссер
Старожил
 
Аватар для ACE Valery
 
Регистрация: 27.04.2007
Сообщений: 3,365
По умолчанию

В следующий раз пользуйтесь правкой предыдущего сообщения, чтоб добавить что-то. Удалять и объединять сообщения форумчане сами не могут.
Если я вас напрягаю или раздражаю, вы всегда можете забиться в угол и поплакать
ACE Valery вне форума Ответить с цитированием
Старый 20.03.2012, 21:31   #8
Elloriane
Пользователь
 
Регистрация: 19.02.2012
Сообщений: 60
По умолчанию

ACE Valery, я понял
Проблема больше не актуальна - решил переписать с нуля - все работает теперь
Elloriane вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Задача на Паскале(возможно с указателями) pahann Помощь студентам 1 31.01.2011 15:51
Возможно проблема в видеокарте или материнке Иллея Компьютерное железо 20 19.12.2009 22:32
часы показывают m часов, n минут и k секунд. Каковы будут показатели часов через p часов, q минут и r сек Паскалька^^ Помощь студентам 3 11.10.2009 19:41
Проблема в Delphi. Возможно, на потоки. Jean-Esther Помощь студентам 2 21.02.2009 22:32
Задача паскаля!Возможно надо что то добавить??? Impario Помощь студентам 7 29.12.2008 14:50