Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Как такое может быть?!


Автор: math_beginer 31.3.2004, 09:15
Есть такой код:
{
...
double **array;
array=new double *[row]
if(!array){
ShowMessage("...");exit(1);}
for(int i=0;i<row;i++)
{
array[i]=new double [colomn];
if(!array[i])
{ShowMessage("...");exit(1);}
}
...
Проблема в том, что в строке
array[i]=new double [colomn];
при i меньшем row при выполнении вываливается сообщение об ошибке:
"Access violation at address... etc"

Почему так, и как с этим бороться? Заранее благодарен

Автор: maxim1000 31.3.2004, 10:07
вообще-то желательно бы привести весь код, чтобы люди могли запустить его у себя, попробовать...

Автор: OlegsDP 31.3.2004, 10:18
Я попробовал вот такую программку - все работает.

Код

#include <stdio.h>
#include <windows.h>

void main ()
{
 int row = 30, colomn = 10;
 double **array = new double*[row];

 if(!array){
   printf("!array\r\n");exit(1);
 }
 for(int i = 0; i < row; i++) {
   array[i]=new double [colomn];
   if(!array[i]) {
     printf ("!array[i]\r\n");
     exit(1);
   }
   for (int j = 0; j < colomn; j++) array[i][j] = colomn * i + j;
 }

 for(i = 0; i < row; i++) {
   for (int j = 0; j < colomn; j++) {
     printf ("%3.0f ", array[i][j]);
   }
   printf ("\r\n");
 }
}


А в Вашем коде в строке

Код

array=new double *[row]


отсутствует ';'

Автор: math_beginer 31.3.2004, 10:58
Цитата
вообще-то желательно бы привести весь код, чтобы люди могли запустить его у себя, попробовать...

Я бы срадостью, только код большой. Вообще-то это выполняется в констукторе класса, который является членом другого класса, все это делается в циклах и т.д.
вот кусок описания класса:

class matrica{
protected:
double **array;
int row,colomn;
public:
...
matrica(int a,int b);
...
};
вот конструктор:
matrica::matrica(int a,int b)
{row=a;colomn=b;
array=new double * [row];
if(!array){cout<<"!array";getch();exit(1);}
for(int i=0;i<row;i++)
{
array[i]=new double [colomn];
if(!array[i]){cout<<"!array[i]!";getch();exit(1);}
}
}
Цитата
Я попробовал вот такую программку - все работает.

Сам по себе приведенный код у меня тоже работает, объекты (матрицы) создаются, перемножаются, инвертируются, память после использования освождается и т.д.
Но вся беда втом что в этой программе столько нагромождено, что локализовать ошибку у меня не получается sad.gif

Автор: bel_nikita 31.3.2004, 17:38
Цитата
Но вся беда втом что в этой программе столько нагромождено, что локализовать ошибку у меня не получается

Дык, а для чего тогда DEBUG режим?
Я не знаю, как там в Борландах, но если у тебя MVC, запусти дебаггер, и когда прога вылетит посмотри Call Stack.
Можно exception подрубить и посмотреть.

Автор: DenDen 31.3.2004, 19:52
Строго говоря, когда создаются указатель они в Борландах НЕ ОБЯЗАТЕЛЬНО NULL перед каждым объявлением принудительно присваевай каждому указателю NUUL.

Автор: Fantasist 31.3.2004, 20:38
Цитата
Строго говоря, когда создаются указатель они в Борландах НЕ ОБЯЗАТЕЛЬНО NULL


Это не только в Борландах. Строго говоря, new должен выбрасывать bad_alloc, если выделить память не удалось, и уж по крайней мере возвращать 0.


Цитата
Но вся беда втом что в этой программе столько нагромождено, что локализовать ошибку у меня не получается


Хе. Так придется. Здесь мы тебе ошибку не локализуем.

Автор: srd 1.4.2004, 05:48
Цитата
Это не только в Борландах

В MSVC++ в отладочной версии неинициализированным указателям автоматом присваивается 0xcccccccc. В релизной версии проекта, разумеется, ничего подобного не делается.
Цитата
Строго говоря, new должен выбрасывать bad_alloc, если выделить память не удалось, и уж по крайней мере возвращать 0.

Если включен какой-нибудь хедер из STL, хотя бы <new>, то бросается bad_alloc, если STL не используется, то оператор new просто вернет нулевой указатель.

Автор: math_beginer 1.4.2004, 14:17
Цитата
принудительно присваевай каждому указателю NUUL.

Так я уже пробовал так делать - никакой разницы, похоже что ошибка на самом деле не там где о ней выдается сообщение...
Будем искать...

Автор: bel_nikita 1.4.2004, 16:57
Цитата
Сам по себе приведенный код у меня тоже работает, объекты (матрицы) создаются, перемножаются, инвертируются, память после использования освождается и т.д.

Так может с delet'ом проблемы?
Что юзаешь, Борланд аль Визуал.
Если Визуал, то посмотри Call Stack. Увидешь фукцию, где прога виснет (ну, возможно)

Автор: maxim1000 1.4.2004, 17:41
можно попробовать так:
удалять части программы, пока эта ошибка остается
довольно часто таким образом получается не очень большая программка, которая глючит и размер имеет небольшой...

Автор: math_beginer 1.4.2004, 17:53
Цитата
Так может с delet'ом проблемы?

кажется, нет. У меня раньше прога память кушала, так я спецально проверял - делал в больших циклах большие матрицы. Так что освобождается все нормально.
Цитата
Что юзаешь, Борланд аль Визуал.
Если Визуал, то посмотри Call Stack. Увидешь фукцию, где прога виснет (ну, возможно)

Визуал вообще ни разу не видел. Но вборланде такое тоже есть. Тока я не знаю как это дело работает...
поэтому пока пользуюсь проверенным способом:
Цитата
удалять части программы, пока эта ошибка остается
довольно часто таким образом получается не очень большая программка, которая глючит и размер имеет небольшой...

Автор: bel_nikita 2.4.2004, 14:07
Цитата
поэтому пока пользуюсь проверенным способом

Да, нет, не прав ты. Если бы способ был проверен, то уже давно бы нашел ошибку wink.gif
Цитата
Визуал вообще ни разу не видел. Но вборланде такое тоже есть. Тока я не знаю как это дело работает...

Запускаешь прогу в дебаге. Когда прога сваливается. Смотришь Call Stack. И в ентом самом Call Stack увидешь функцию (то местно в проге) где софт вылетает. А дальше дело техники smile.gif

Thread'ы юзаешь??

Автор: DenDen 2.4.2004, 15:51
Это ж как его добыть, то чего неможет быть?
А вообще смени new/delete на malloc/free--и отлаживать легче и лучше понимаешь,что там творится....Лучше замолчать, пока поклонники Страуструпа не забили меня "C++ 3-d Edition",тяжелая книженция,понимаешь smile.gif

Автор: OlegsDP 2.4.2004, 15:59
Цитата
И в ентом самом Call Stack увидешь функцию (то местно в проге) где софт вылетает. А дальше дело техники


Так ведь проблема в том, что программа рушится совсем не там, где ошибка. Я в таких случаях делаю так: заключаю в комментарии все, что может вызывать ошибку. После этого ошибки нет. Затем начинаю постепенно снимать комментарии и проверять, не проявляется ли ошибка. Таким образом мне удавалось отловить "неуловимые" ошибки даже в Ч_У_Ж_И_Х проектах.

Автор: math_beginer 2.4.2004, 16:09
Цитата
Thread'ы юзаешь??

Вот, точно, сделал без потоков - все работает smile.gif. Только почему в потоках неработает - все равно не понятно...
Цитата
А вообще смени new/delete на malloc/free--и отлаживать легче и лучше

А вчем разница?

Автор: bel_nikita 2.4.2004, 16:36
to OlegsDP
Цитата
Так ведь проблема в том, что программа рушится совсем не там, где ошибка

Программа всегда рушится только там, где ошибка wink.gif
Включаете ДЕБАГ режим. Запускаете софт. Софт вылетает, типа Access Violation и т.п.
В Call Stack будет находиться текущаю функция, т.е. фукция в которой произошел сбой!
Смотрите параметры функции и т.п. Т.е. возможно локализовать ошибку без комментария.
to math_beginer
Цитата
Вот, точно, сделал без потоков - все работает . Только почему в потоках неработает - все равно не понятно...

Синхронизация нам поможет tounge.gif

Разные треды иммеют доступ к ресурсу! А это очень плохо. Надо синхронизировать доступ

Автор: math_beginer 2.4.2004, 17:05
Цитата
Программа всегда рушится только там, где ошибка

Но ведь в данном конкретном случае это не так!!!
Сам по себе конструктор работает! И что самое непонятное: Принудительно присваеваем указателю NULL (допустим даже, что при этом теряется память). ПОЧЕМУ NULL-вому указателю не может быть выделена память????? Даже пусть память не выделяется, но не работает ведь именно оператор new, до проверки выделилась память или нет программа даже не доходит!!
ЗЫ Я скоро уже начну сомневаться что С++ самый надежный язык программирования butbut.gif

Автор: bel_nikita 2.4.2004, 18:07
math_beginer
А в борланде проверка типа
Код
char* p=new char[100];
if (p==NULL ) ....

не катит. Как я знаю ( сам борланд не юзаю ) тама генерится ecxeption bad_allocate. Так что в строку if (p==NULL ) ты уже ни как не попадешь.
Цитата
ЗЫ Я скоро уже начну сомневаться что С++ самый надежный язык программирования

А что ты понимаешь под надежностью???
С++ это скорее мощный инструмент для программирования, а надежность тут не причем

Что-то мы отвлеклись от темы. Так что у тебя за проблемы?

РS: Еще раз: программа рушится только там где ошибка wink.gif

Автор: srd 2.4.2004, 20:36
Цитата
А вообще смени new/delete на malloc/free--и отлаживать легче и лучше

В программах на C++ этого делать ни в коем случа нельзя. new/delete вызывают конструктор и деструктор, а malloc/free нет.

Цитата
Как я знаю ( сам борланд не юзаю ) тама генерится ecxeption bad_allocate. Так что в строку if (p==NULL ) ты уже ни как не попадешь.

Повторюсь, но скажу, что и в MSVC++ в случае неудачи new кидает bad_alloc, если включен любой хедер из STL, т.к. они включают стандартный заголовок <new>

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)