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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 03.11.2011, 14:15   #1
pinkiller
Форумчанин
 
Регистрация: 29.10.2011
Сообщений: 141
По умолчанию Странные ошибки

Код:
#include <iostream>
#include <stdio.h>
using namespace std;


int ChangeArray(char** array, int f){
  int d=f; 
  f=f*2;
  char* newArray = new char[f];
  //Унарная * - оператор разыменования указателя, "вытащить то, адрес чего хранится в переменной"
  for (int i=0; i<=d; i++) {newArray[i]=(*array)[i];}
  delete[] (*array);
  *array=newArray;
  return f;
}


int test (int a,int b,char te[], char tx[]) {    // проверка "нового" Термина на наличае в списке терминов
	int q=1;
		for (int c=0; te[c]!='\0';c++) {
			if (te[c]=='0'){
				for (int d=c; te[d]!='0';d++,a++) {
					if (a<=b) {if (tx[a]!=te[d]) return 0;}
					if ((te[b+1])=='\0') return 0;
				                              } 
			               }
			                           } return 1;
	                                         }
char record (int a,int b,char te[], char tx[], int z, int &v) {   // запись нового Термина в массив терминов
	int d, c, u;
	c=b-a;
	for (int i=0; te[i]!='\0'; i++) {
		if (te[i]=='0') {d=i;}
		if (te[i]=='\0') {u=i;}
	                                }
	if ((u-d)<c)                                   // расширение списка терминов если выделенной памяти не хватает
	{
    z=ChangeArray(&te, z);
	}
	
	/*      sz*=2;                                // удвоить размерность
            int *q=new int[sz];               // создать новый
            for (int i=0;i<n;i++)              // копировать старый в новый 
                        q[i]=p[i];             
            delete p;                            // уничтожить старый
            p=q;                                  // считать новый за старый
	
	}*/
	for (int p=a; p<=b; p++) {
	     te[d+1]=tx[a];                    
	                     }
	return *te;
}
                    

void main () {
int e=0, i, v, m;
int z=100;
FILE *txt;
char* term = new char[z];

if((txt=fopen("txt.txt", "r")) == NULL)  // вроде как функция корректно открывающая поток
{
   printf("Error\n");
   exit(1);   
}

for(i=0;char t=getc(txt)!=EOF; i++); // Посимвольное чтение
{m=i;} // длинна файла     
char* TXT = new char[m]; // инициализация массива под текст нужной длинны
for (i=0; i<=m+1; i++) { 
	TXT[i]=getc(txt);   // записывание текста в массив
                     }

for (i=0; i<=m; i++) {   
	if (TXT[i]>='A' && TXT[i]<='Z') {  // ищем первую большую букву чтобы найти термин
		if  (TXT[i+1]>='A' && TXT[i+1]<='Z') {  // Если и вторая буква большая то это точно термин а не начало предложения или имени с большой буквы
			e=i;
		for (;TXT[e]<='A' && TXT[e]>='Z'; e++)  // находим конец термина
			if (test(i,e,term,TXT)==0) {                    // если такого термина еще нет в массиве терминов
			*term=record(i,e,term,TXT,z,v);                      // записываем                                		
			z=v;
			}
			i=e+1; // вне зависимости от того записали мы Термин или нет, продолжаем со следующей после термина буквы.		
			
			}     }  }

delete[] TXT;
delete[] term;
}



Выдает странную ошибку и говорит что в определенный момент поток открытый с помощью fopen устаревает.
Как с этим бороться?
pinkiller вне форума Ответить с цитированием
Старый 03.11.2011, 14:26   #2
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Когда Вы открываете файл, для него появляется т.н. "курсор" - программа запоминает, на какой букве она остановилась.
Код:
for(i=0;char t=getc(txt)!=EOF; i++);
Что здесь происходит? Раз за разом читаются символы из файла. При каждом чтении курсор сдвигается на одну позицию (иначе мы бы читали раз за разом первый символ). В итоге, мы доходим до конца файла.
Далее,
Код:
{m=i;} // длинна файла     
char* TXT = new char[m]; // инициализация массива под текст нужной длинны
for (i=0; i<=m+1; i++) { 
    TXT[i]=getc(txt);   // записывание текста в массив
                     }
Мы снова вызываем getc(). Но откуда программе знать, что мы собрались читать снова от начала файла? Ниоткуда. Вывод: ей надо об этом сказать. Для этого используется функция перемещения курсора fseek().
Abstraction вне форума Ответить с цитированием
Старый 03.11.2011, 15:12   #3
pinkiller
Форумчанин
 
Регистрация: 29.10.2011
Сообщений: 141
По умолчанию

Код:
fseek(txt, 0L, 0);
/* Перейти в начало файла */

Попробовал сделать вот так. ошибка та же...
pinkiller вне форума Ответить с цитированием
Старый 03.11.2011, 15:21   #4
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Что именно за ошибка? Как выглядит, в какой момент возникает?
Abstraction вне форума Ответить с цитированием
Старый 03.11.2011, 15:30   #5
pinkiller
Форумчанин
 
Регистрация: 29.10.2011
Сообщений: 141
По умолчанию

вообщем нынешний код такой такой:
Код:
#include <iostream>
#include <stdio.h>
#include <io.h>
using namespace std;


int ChangeArray(char** array, int f){
  int d=f; 
  f=f*2;
  char* newArray = new char[f];
  //Унарная * - оператор разыменования указателя, "вытащить то, адрес чего хранится в переменной"
  for (int i=0; i<=d; i++) {newArray[i]=(*array)[i];}
  delete[] (*array);
  *array=newArray;
  return f;
}


int test (int a,int b,char te[], char tx[]) {    // проверка "нового" Термина на наличае в списке терминов
	int q=1;
		for (int c=0; te[c]!='\0';c++) {
			if (te[c]=='0'){
				for (int d=c; te[d]!='0';d++,a++) {
					if (a<=b) {if (tx[a]!=te[d]) return 0;}
					if ((te[b+1])=='\0') return 0;
				                              } 
			               }
			                           } return 1;
	                                         }
char record (int a,int b,char te[], char tx[], int z, int &v) {   // запись нового Термина в массив терминов
	int d, c, u;
	c=b-a;
	for (int i=0; te[i]!='\0'; i++) {
		if (te[i]=='0') {d=i;}
		if (te[i]=='\0') {u=i;}
	                                }
	if ((u-d)<c)                                   // расширение списка терминов если выделенной памяти не хватает
	{
    z=ChangeArray(&te, z);
	}
	
	/*      sz*=2;                                // удвоить размерность
            int *q=new int[sz];               // создать новый
            for (int i=0;i<n;i++)              // копировать старый в новый 
                        q[i]=p[i];             
            delete p;                            // уничтожить старый
            p=q;                                  // считать новый за старый
	
	}*/
	for (int p=a; p<=b; p++) {
	     te[d+1]=tx[a];                    
	                     }
	return *te;
}
                    

void main () {
int e=0, i, v, m;
int z=100;
FILE *txt;
char* term = new char[z];

if((txt=fopen("txt.txt", "r")) == NULL)  // вроде как функция корректно открывающая поток
{
   printf("Error\n");
   exit(1);   
}

for(i=0;char t=getc(txt)!=EOF; i++); // Посимвольное чтение
{m=i;} // длинна файла     
char* TXT = new char[m]; // инициализация массива под текст нужной длинны
fseek(txt, 0L, SEEK_SET);   /* Перейти в начало файла */
for (i=0; i<=m+1; i++) { 
	TXT[i]=getc(txt);   // записывание текста в массив
                     }

for (i=0; i<=m; i++) {   
	if (TXT[i]>='A' && TXT[i]<='Z') {  // ищем первую большую букву чтобы найти термин
		if  (TXT[i+1]>='A' && TXT[i+1]<='Z') {  // Если и вторая буква большая то это точно термин а не начало предложения или имени с большой буквы
			e=i;
		for (;TXT[e]>='A' && TXT[e]<='Z'; e++);  // находим конец термина
			if (test(i,e,term,TXT)==0) {                    // если такого термина еще нет в массиве терминов
			*term=record(i,e,term,TXT,z,v);                      // записываем                                		
			z=v;
			}
			i=e+1; // вне зависимости от того записали мы Термин или нет, продолжаем со следующей после термина буквы.		
			
			}     }  }

delete[] TXT;
delete[] term;
}
Ошибка возникает во время компиляции, причем не отображаеться в Error list а вылетает окошко с системной ошибкой HEAP CORRUPTION, что то такое.
еще есть варнинг о том что fopen устаревший.

А еще пока изучал функцию fseek нашел информацию о том что различается ее использование с двоичными и текстовыми файлами. но в чем не понял
pinkiller вне форума Ответить с цитированием
Старый 03.11.2011, 15:58   #6
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Это больше похоже на ошибку компилятора - чем компилируем?
Уберите iostream, всё равно он здесь не используется. И зачем нужен заголовок io.h?

Что же до "варнинг о том что fopen устаревший" - так прочитайте текст предупреждения. Это должно быть что-то вроде "fopen() - устаревшая функция с проблемами безопасности, рекомендуется заменить на fopen_s()".
Abstraction вне форума Ответить с цитированием
Старый 03.11.2011, 16:10   #7
Sam Gold
Форумчанин
 
Аватар для Sam Gold
 
Регистрация: 26.03.2010
Сообщений: 538
По умолчанию

Цитата:
Код:
char* TXT = new char[m]; // инициализация массива под текст нужной длинны
for (i=0; i<=m+1; i++) { 
	TXT[i]=getc(txt);   // записывание текста в массив
for (i=0; i<=m; i++){
if (TXT[i]>='A' && TXT[i]<='Z') {
Лезешь за пределы выделенной памяти - в данных циклах должно быть меньше i < m.
Единственный способ стать умнее - играть с более умным противником.
Sam Gold вне форума Ответить с цитированием
Старый 03.11.2011, 16:11   #8
pinkiller
Форумчанин
 
Регистрация: 29.10.2011
Сообщений: 141
По умолчанию

Debug Error!

Program:...

HEAP CORRUPTION DETECTED: after Normal block (#53) at тут всякие цыферки) CRT detected that the applicatoin wrote the memory after end of heap buffer.
pinkiller вне форума Ответить с цитированием
Старый 03.11.2011, 16:22   #9
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Это при компиляции, или при выполнении?
Если второе, то да, ищем ошибки вылета за границы массива. Во втором цикле даже i=m-1 будет ошибочным, ибо есть обращение к TXT[i+1]. Так что а) выделите памяти на байт больше, б) озаботьтесь дописать в конец массива '\0' или ещё что-нибудь, чтобы for (;TXT[e]>='A' && TXT[e]<='Z'; e++); не увело за границы массива, опять же.
Abstraction вне форума Ответить с цитированием
Старый 03.11.2011, 18:05   #10
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,709
По умолчанию

Ошибка говорит, что вы лезете в памяти не туда... Так причем тут файл?
p51x вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Странные баги в FB delphicoding БД в Delphi 8 01.08.2011 14:27
Странные таблицы Port Microsoft Office Word 4 18.05.2011 12:01
Странные ошибки при компиляции в Visual studia C# 2008 skild Общие вопросы .NET 2 21.02.2010 23:38
Странные ошибки. Rio309 Общие вопросы Delphi 2 19.10.2009 19:22
Странные задачи L_M Свободное общение 60 19.05.2009 08:54