Автор
|
Тема: Бьюсь в закрытую дверь, откройте ее
|
Rechkin |
опубликован 28-01-2002 18:58 MSK
Вроде идеальный код, а не работает void Proiz (double*RealOut,double*ImagOut,int WH) { for (int i = 0; i < WH; i++){ RealOut[i]=RealSpEt[i]*RealOut[i]+ImagSpEt[i]*ImagOut[i]; ImagOut[i]=RealSpEt[i]*ImagOut[i]-RealOut[i]*ImagSpEt[i]; } } А так работает void Proiz (double*RealOut,double*ImagOut,int WH) { for (int i = 0; i < WH; i++){ RealOut[i]=RealSpEt[i]; ImagOut[i]=RealSpEt[i]; } } Массивы 288*288 Пишет Invalid pointer optrator и втыкает, да так что помогает только перезагрузка В дебагере на i=13 зависает RealSpEt[i] и ImagSpEt[i]; глобальные переменные
|
gonzales
|
опубликован 28-01-2002 20:31 MSK
Знаешь , я на си около 3 месяцев пишу и особо в этом не рублю, но по-мойму в строке RealOut[i]=RealSpEt[i]*RealOut[i]+ImagSpEt[i]*ImagOut[i]; ты умножаешь не на чиcло ,а на указатель. Я точно не уверен так как раньше писал на Паскале , но возможно из-за этого. |
Rechkin
|
опубликован 28-01-2002 20:54 MSK
Нет это не из-за этого, так как если рассматривать массив 2*2 то все прекрасно работает
|
Student
|
опубликован 28-01-2002 22:16 MSK
А может выходишь за границы массивов. Судя по твоему примеру, размеры ВСЕХ массивов ДОЛЖНЫ быть одинаковыми. |
Valery
|
опубликован 28-01-2002 22:31 MSK
что-то странно, говоришь, что массивы у тебя 2-х мерные, а сам работаешь, как с одномерными, конечно если бы все массивы у тебя передавались бы как параметры, то фигня, компилятор можно было бы убедить, что работаем с одномерными, но с глобальными массивами... нда. Ты бы хоть привел как ты эту функцию вызываешь, что ли. Не удивлюсь если забыл в качестве размера передаешь просто sizeof(array), для массива 288*288 double при этом получишь кстати дюже много 663552, дык конечно куда не надо залезешь. Вообщем мало данных. |
gonzales
|
опубликован 28-01-2002 23:24 MSK
Ты мне объясни. Мне самому интересно. У тебя ImagOut[i] типа double* то есть указатель на double. Ты пишешь a * ImagOut[i] то есть , a умножить на адресс переменной. |
SUnteXx
|
опубликован 29-01-2002 12:52 MSK
Я согласен с gonzales, но я не уверен на 100%. Раз у тебя передаются не адреса памяти и не переменные, а только поинтеры на них, то надо попробовать перемножать поинтера поинтера, т.е. значения, а то получается, что ты умнажаешь не на число, а на поинтер, что не есть хорошо. Попробуй так:RealOut[i]=(*RealSpEt[i])*(*RealOut[i])+(*ImagSpEt[i])*(*ImagOut[i]); или void Proiz (double*RealOut,double*ImagOut,int WH) { for (int i = 0; i < WH; i++) { double d, d1, d2, d3, d4; d = (double)RealSpEt[i]; d1 = (double)*RealOut[i]; d2 = (double)ImagSpEt[i]; d3 = (double)*ImagOut[i]; d4 = d*d1+d2*d3; RealOut[i] = d4; . . . } } А то у тебя RealOut[i] = ... * RealOut[i] + ... И еще, знаешь, почему у тебя работает "RealOut[i]=RealSpEt[i];", потому что поинтер = поинтеру, а это номально!)
|
Valery
|
опубликован 29-01-2002 08:40 MSK
не, тут все нормально, указатель на тип вполне может рассматриваться как массив, одномерный или двумерный все равно. Кстати предыдущую свою реплику поправлю: если глобальные массивы объявлены как указатели, то с точки зрения компилятора все будет нормально, но вот выделил ли ты их в памяти, это тогда вопрос. Вообщем, приводи все окружение вызова твоей функции и сам вызов, тогда будет видно. |
MakTest
|
опубликован 29-01-2002 09:59 MSK
Ты массивы: RealOut,ImagOut, и т.д. как объявлял? Они выглядят в коде как одномерные, а ты пишешь, что NN*NN. Странно, что тогда это вообще компилится (хотя может, особенно в C++ Builder, - ты не в нем работаешь?). Вообще, скорее всего ошибка тут и есть - ведь если, к примеру, RealOut[288][288], то RealOut[i] это *(RealOut + i), то есть указатель на i-тую строку массива, и для доступа к элементу нужно указать еще один сдвиг и еще раз разадресовать. Ну и еще стандартный вопрос: WH за границы не сбегает? Хотя если да, то сообщение об ошибке будет скорее начинаться с "Access violation..." А вообще |
MakTest
|
опубликован 29-01-2002 10:01 MSK
sorry, рано Enter нажал. А вообще, напиши все свои объявления массивов. |
Rechkin
|
опубликован 29-01-2002 13:43 MSK
Массив действительно духмерный по сути задачи, но в программе он представлен как вектор(одномерный массив), с этим все впорядке везде работаетОбъевление массива double *RealSpEt, ImagSpEt; далее захват памяти RealSpEt = CreateDoubleBuffer(288*288); ImagSpEt = CreateDoubleBuffer(288*288); где double *CreateDoubleBuffer (DWORD BufferLength) { double *Buffer; if ((Buffer = new double [BufferLength])!= NULL) return Buffer; else return NULL; }
|
Alvengo
|
опубликован 29-01-2002 14:17 MSK
В данной записи ImagSpEt это дабл, а не указатель на дабл, как, видимо, нужно.... |
MakTest
|
опубликован 29-01-2002 14:43 MSK
А если по-простому? Вот так (можно заключить в блок try...catch):const int BufferLength = 288*288; double *RealSpEt = new double [BufferLength]; double *ImagSpEt = new double [BufferLength]; Код гораздо экономичнее. А в твоей функции память динамически выделяется и не освобождается. И функция зовется 2 раза подряд. Память тут явно течет, и вообще, по-моему, так как-то не смотрится. По мелочи: если уж (Buffer ... != NULL), то и объявлять надо с обнулением: double *Buffer = NULL;
|
Valery
|
опубликован 29-01-2002 16:26 MSK
просто удивительно, как народ сопротивляется, чтоб ему помогли. :) в час по чайной ложке. тем более, что код не реальный берет, а перенабирает, с чем лишние ошибки связаны. |
Student
|
опубликован 29-01-2002 17:54 MSK
double *RealSpEt, ImagSpEt; // ---> ошибка double *RealSpEt, *ImagSpEt; // ---> правильно// можно проще: double *CreateDoubleBuffer (const DWORD dwSize) { return (new double[dwSize]); // если облом, то оператор new возвращает NULL // иначе, адрес выделенного блока памяти } 2SUnteXx: >> ты умнажаешь не на число, а на пойнтер... Если бы функция была бы определена как void Proiz (double **RealOut, double **ImagOut, int WH), то ты был бы прав. |
SUnteXx
|
опубликован 30-01-2002 12:01 MSK
2Student: Поверю тебе на сей раззз:) |
Drunkard
|
опубликован 31-01-2002 05:08 MSK
Вот тело твоего цикла: RealOut[i]=RealSpEt[i]*RealOut[i]+ImagSpEt[i]*ImagOut[i]; ImagOut[i]=RealSpEt[i]*ImagOut[i]-RealOut[i]*ImagSpEt[i];По правилам языка Си RealOut и ImageOut это указатели на первый элемент массивов, поэтому, чтобы заработало следует писать так *(RealOut+i)=RealSpEt[i]*(*(RealOut+i))+ImagSpEt[i]*(*(ImagOut+i)); Вторая строчка - аналогично. Поясню. Можно сделать по другому. Смотри, к примеру, обьявим переменные double A,B; и тогда в теле цикла можно записать А=*(RealOut+i);// Это и есть значение i-го элемента массива RealOut B=*(ImagOut+i););// Это и есть значение i-го элемента массива ImagOut и тогда первая строка из цикла будет писаться так A=RealSpEt[i]*A+ImagSpEt[i]*B; что читается лучше, но суть одно и то же! |
Drunkard
|
опубликован 31-01-2002 05:12 MSK
Да забыл! Больше не бейся - дверь открыта! :))) |
Valery
|
опубликован 31-01-2002 08:31 MSK
чего-то мы тут раздухарились, уж и автор исходной мессаги давно ушел (наверное вдоль забора искать другую калитку), а мы все спорим... :) |
ingvarr
|
опубликован 31-01-2002 12:37 MSK
Бред какой-то! Поправте меня, если я ошибаюсь, но по-моему b*(*(a+i)) эквивалентно b*a[i],где а - указатель (причем оператор [] имеет больший приоритет, чем оператор *), double *a = new double[n] - это одномерный массив, элемент которого - a[i]. Единственная ошибка, которую я нашел - это, действительно, в объявлении. А то что автора нету (мне кажется, он решил через окно (98:-)) - это ничего. Главное, что он идею подкинул. С уважением ingvarr |
Rechkin
|
опубликован 31-01-2002 18:05 MSK
Приветствую почтейнейших, спасибо за различные советы. Удивительно, но факт на работе исходный код заработал как миленький,поэтому и не отвечал зависал на работе, а инета там нет! А в объявлении просто опечатка. Все-таки интересно все-таки сколькими способами можно решить даннубю задачу! Все равно большое спасибо за ЛИКБЕЗ! Надо открыть такую рубрику "решение одной задачи несколькими способами" |