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


Автор: PandaRus 27.12.2006, 12:17
    Добный день.

    Одной из составных частей моего диплома является расчет распределения токов в теле человека между электродами. Пишу в Visual C++. Вообще вперые в С++.
    Столкнулся с проблемой, что как только объем обьявленных переменных превысит где-то 1.5Мб программа перестает работать. Программа использут для расчета матрицу проводимостей - требуется массив около 65000х65000 (что соответствует телу, разбитому на 100х25х25 точек).
    Очень жаль при объеме ОЗУ в Гб получить от программы 1Мб.
Подскажите, можно ли в программе задавать любой объем используемой памяти.

С уважением, Иван. Срочно. smile 

Автор: JackYF 27.12.2006, 12:21
У тебя объявление статическое? Тогда увеличь максмальный размер стека (должно быть в настройках проекта).
Если динамическое, то такого быть не должно и код на выкладку.

Автор: PandaRus 27.12.2006, 17:55
Насчет объявления - не знаю. Как запустил программу - инчего не менял. В тулсах>опции вроде все облазил - что-то про память не нашел. 
От текса моей программы не зависит, так как не работает даже такая голая программа:

Код

#include <stdio.h>
#include <conio.h>
#include <math.h>
//pragma argsused
int main()
{
   float A[1000][1000];
   getch();
   return 0;
}


При запуске появляется стандартное окно Винды об ошибке о том, что в моем "..." .exe обнаружена ошибка.

У меня Visual6.0. Может попробовать на другом компе или например на Байсике?

Автор: JackYF 27.12.2006, 18:02
Цитата(PandaRus @  27.12.2006,  17:55 Найти цитируемый пост)
float A[1000][1000];


Ты пытаешься в стеке выделять sizeof(float) * 1000 * 1000 = ~4Мб памяти! Статически. По умолчания программа не имеет столько большого стека!

Выделяй это дело динамически.
Как - поиск по форуму, тема поднималась не раз - "Динамическое выделение памяти".

Добавлено @ 18:04 
Код

float** A = new float*[1000];
for ( int i = 0; i < 1000; ++i )
{
  A[i] = new float[1000];
}


А вообще место 1000 лучше использовать целые константы.

Автор: Любитель 27.12.2006, 18:23
Про делит надо было бы напомнить, а то многие начинающие забывают.

Автор: JackYF 27.12.2006, 18:31
Не вопрос: напоминаю: smile

в конце использования данной памяти ее очень желательно освободить:
Код

for ( int i = 0; i < 1000; ++i )
{
  delete [] A[i];
}
delete [] A;

Автор: PandaRus 27.12.2006, 19:13
Большое спасибо за оперативность smile  и особенно JackYF за добавление с примером.
А если выделять память под B=XxYxZ то будет так?:

Код

float** B = new float*[Z];
for ( int i = 0; i < X; i++ )
for ( int j = 0; j< Y; j++)
{
  B[i][j] = new float[Z];
}

for ( int i = 0; i < X; ++i )
   for ( int i = 0; i < Y; ++j )
{
  delete [] B[i][j];
}
delete [] B;

Автор: Любитель 27.12.2006, 19:19
Нет. Трёхмерный массив - это массив из двумерных массивов. Типа такого:
Код

float*** B = new float**[Z];
for (int i = 0; i < Z; ++i)
{
   B[i] = new float*[Y];
   for (int j = 0; j < Y; ++j)
     B[i][j] = new float[X];
}


Аналогично удаление.

А ты уверен, что тебя трёхмерный массив, нужен кстати. Может стоит посмотреть в сторону каких-нибудь математических библиотек (с хорошей оптимизацией)?

Автор: PandaRus 27.12.2006, 19:36
   Трехмерные массивы только для ввода/вывода характеристик тела (матрицы: потенциалов[x][y][z] в точках и проводимостей между этими точками). Под них память выделять не буду - и так хватит. Но вот для расчетов потребуется гигантская матрица проводимостей G=[x*y*z][x*y*z]- по расчетам уйдет около 250 метров.
    В основе решения - метод узловых потенциалов - результат получается очень быстро (для больших массивов) при использовании к G метода Гаусса.
    Пока правда программа работает в плоскости, предстаит добавление еще одной координаты Z. Предчувсвую кипени мозгов при составлении G. smile 

Автор: MINI_PROGRAMMER 28.12.2006, 22:47
Товарищи! Программирую Windows-окна. Недавно узнал про PlaySound, создал програмку, скомпилировал.
ОШИБКА!   [Linker error] undefined reference to `PlaySoundA@12' .
Подскажите, в чём дело!  smile
Работаю в Dev-C++ v. 4.9.9.2

Автор: JackYF 28.12.2006, 22:59
Подключи к проекту winmm.lib

Автор: MINI_PROGRAMMER 29.12.2006, 13:52
Thank you! smile 

Автор: PandaRus 15.1.2007, 20:43
Добрый день.

Подскажите в чем проблема? Вариант для поверхности работает, а что здесь - не знаю. 
Программа немного недоработана по алгоритму, но ошибка не в этом - просто не компилируется.

Код

//=========================================================================================================================
//--------------------------------------- Программа моделирования протекания токов ----------------------------------------
//=========================================================================================================================

#include <stdio.h>
#include <conio.h>
#include <math.h>
int main()
{
    FILE *outfile;
    outfile=fopen("1.txt","w");

    short i,j,m,k,s,r,n,si,rj,h,hm,ii;
    float Ps[15][15][31],Pr[15][16][30],Ph[16][15][30],s1,G1,I1;

    float** G=new float*[6750];
    for(i=0;i<6750;i++)
    {
        G[i]=new float[6750];
    }

    float* Fi=new float[6750];
    float* F=new float[6750];
    float* I=new float[6750];
    float* S=new float[6750];



//Ввод параметров на моделирование------------------------------------------------------------------------------------------
    s=15;                            //размеры тела
    r=30;
    h=15;
    k=s*r*h-1;                        

    for(i=1; i<=k; i++)                //места подключения токовых присосок
        I[i]=0;
    I[3901]=1;
    I[4000]=-1;                         
    
    for(m=1; m<=h; m++)
        for(i=1; i<=s; i++)
            for(j=0; j<=r; j++)
                Ps[m][i][j]=0;
    for(m=1; m<=h; m++)
        for(i=0; i<=s; i++)
            for(j=1; j<=r; j++)
                Pr[m][i][j]=0;
    for(m=0; m<=h; m++)
        for(i=1; i<=s; i++)
            for(j=1; j<=r; j++)
                Ph[m][i][j]=0;

    for(m=1; m<=h; m++)                //задание характеристики тела
        for(i=1; i<=s; i++)
            for(j=1; j<=r-1; j++)
                Ps[m][i][j]=1;
    for(m=1; m<=h; m++)
        for(i=1; i<=s; i++)
            for(j=1; j<=r-1; j++)
                Pr[m][i][j]=1;
    for(m=1; m<=h-1; m++)
        for(i=1; i<=s; i++)
            for(j=1; j<=r; j++)
                Ph[m][i][j]=0.1;
//=========================================================================================================================

//Формирование матрицы проводимостей G-------------------------------------------------------------------------------------
    for(i=1; i<=k; i++)
        for(j=1; j<=k; j++)
            G[i][j]=0;

    for(i=1; i<=k; i++)
        for(j=1; j<=k; j++)
            if(i==j)
            {    
                hm=(i-i%(r*s))/r*s;
                if(hm==0)
                    hm=1;
                ii=i-(hm-1)*r*s;
                rj=ii%r;
                if(rj==0)
                    rj=r;
                if(ii==rj)
                    si=1;
                else
                    si=(ii-rj)/r+1;
                G[i][j]=Pr[hm][si-1][rj]+Pr[hm][si][rj]+Ps[hm][si][rj-1]+Ps[hm][si][rj]+Ph[hm][si][rj]+Ph[hm-1][si][rj];
            }

/*    for(i=1; i<=k; i++)
        for(j=1; j<=k; j++)
        {
            if(j==i+1)
            {
                rj=i%r;
                if(rj==0)
                    rj=r;
                if(i==rj)
                    si=1;
                else
                    si=(i-rj)/r+1;
                G[i][j]=-Ps[hm][si][rj];
            }
            if(j==i-1)
            {
                rj=i%r;
                if(rj==0)
                    rj=r;
                if(i==rj)
                    si=1;
                else
                    si=(i-rj)/r+1;
                G[i][j]=-Ps[hm][si][rj-1];
            }
            if(j==i+r)
            {
                rj=i%r;
                if(rj==0)
                    rj=r;
                if(i==rj)
                    si=1;
                else
                    si=(i-rj)/r+1;
                G[i][j]=-Pr[hm][si][rj];
            }
            if(j==i-r)
            {
                rj=i%r;
                if(rj==0)
                    rj=r;
                if(i==rj)
                    si=1;
                else
                    si=(i-rj)/r+1;
                G[i][j]=-Pr[hm][si-1][rj];
            }
            if(j==i+1)
            {
                rj=i%r;
                if(rj==0)
                    rj=r;
                if(i==rj)
                    si=1;
                else
                    si=(i-rj)/r+1;
                G[i][j]=-Ph[hm][si][rj];
            }
            if(j==i+1)
            {
                rj=i%r;
                if(rj==0)
                    rj=r;
                if(i==rj)
                    si=1;
                else
                    si=(i-rj)/r+1;
                G[i][j]=-Ph[hm][si][rj];
            }
        }                                */
//==========================================================================================================================
//    for(i=1; i<=k; i++)
//    {    
//        printf("\n");
//        for(j=1; j<=k; j++)
//            printf("% 2.0f",G[i][j]);
//    }
//Приведение матрицы G к треугольному виду----------------------------------------------------------------------------------
    for(i=1; i<=k; i++)
    {    
        for(j=1; j<=k; j++)
            S[j]=G[i][j];
        s1=S[i];
        I1=I[i];
        for(j=i+1; j<=k; j++)
            if (G[j][i]!=0)
            {
                G1=G[j][i];
                for(n=i; n<=k; n++)
                    G[j][n]=G[j][n]-S[n]*G1/s1;
                I[j]=I[j]-I1*G1/s1;
            }
    }        
//==========================================================================================================================

//Вычисление потенциалов----------------------------------------------------------------------------------------------------
    Fi[k]=I[k]/G[k][k];
    for(i=k-1; i>=1; i--)
    {    
        F[i]=0;
        for(j=i+1; j<=k; j++)
            F[i]=F[i]+Fi[j]*G[i][j];
        Fi[i]=(I[i]-F[i])/G[i][i];
        
    }
//==========================================================================================================================

//Вывод массива потенциалов в файл------------------------------------------------------------------------------------------    
    for(i=1; i<=k; i++)
    {    
        printf("\n");
//        for(j=1; j<=k; j++)
//            printf("% 3.2f",G[i][j]);
        printf("  % 3.5f",I[i]);
    }
        printf("\n");    printf("\n");
    
    
    Fi[k+1]=0;
    n=1;
    for(i=1; i<=s; i++)
    {
        for(j=1; j<=r; j++)
        {    
            fprintf(outfile,"  % 7.6f",Fi[n],outfile);
            n=n+1;
        }
        fprintf(outfile,"\n");
    }
//==========================================================================================================================

    fclose(outfile);
    for(i=0;i<6750;i++)
    {
        delete [] G[i];
    }
    delete [] G;
    getch();
    return 0;
}




P.S. Как-то уж очень нецеремонно влезли...

Автор: JackYF 15.1.2007, 20:48
Во-первых, следовало бы создать новую тему...
Во-вторых, телепаты в отпуске надолго, ты б сказал, что ли, в каких строках ошибки, 
  мы ж не компиляторы все-таки. smile

Автор: PandaRus 15.1.2007, 21:06
Код

//=========================================================================================================================
//--------------------------------------- Программа моделирования протекания токов ----------------------------------------
//=========================================================================================================================

#include <stdio.h>
#include <conio.h>
#include <math.h>
int main()
{
    FILE *outfile;
    outfile=fopen("1.txt","w");

    short i,j,m,k,s,r,n,si,rj,h,hm,ii;
    float Ps[15][15][31],Pr[15][16][30],Ph[16][15][30],s1,G1,I1;

    float** G=new float*[6750];
    for(i=0;i<6750;i++)
    {
        G[i]=new float[6750];
    }

    float* Fi=new float[6750];
    float* F=new float[6750];
    float* I=new float[6750];
    float* S=new float[6750];



//Ввод параметров на моделирование------------------------------------------------------------------------------------------
    s=15;                            //размеры тела
    r=30;
    h=15;
    k=s*r*h-1;                        

    for(i=1; i<=k; i++)                //места подключения токовых присосок
        I[i]=0;
    I[3901]=1;
    I[4000]=-1;                         
    
    for(m=1; m<=h; m++)
        for(i=1; i<=s; i++)
            for(j=0; j<=r; j++)
                Ps[m][i][j]=0;
    for(m=1; m<=h; m++)
        for(i=0; i<=s; i++)
            for(j=1; j<=r; j++)
                Pr[m][i][j]=0;
    for(m=0; m<=h; m++)
        for(i=1; i<=s; i++)
            for(j=1; j<=r; j++)
                Ph[m][i][j]=0;

    for(m=1; m<=h; m++)                //задание характеристики тела
        for(i=1; i<=s; i++)
            for(j=1; j<=r-1; j++)
                Ps[m][i][j]=1;
    for(m=1; m<=h; m++)
        for(i=1; i<=s; i++)
            for(j=1; j<=r-1; j++)
                Pr[m][i][j]=1;
    for(m=1; m<=h-1; m++)
        for(i=1; i<=s; i++)
            for(j=1; j<=r; j++)
                Ph[m][i][j]=0.1;
//=========================================================================================================================

//Формирование матрицы проводимостей G-------------------------------------------------------------------------------------
    for(i=1; i<=k; i++)
        for(j=1; j<=k; j++)
            G[i][j]=0;

    for(i=1; i<=k; i++)
        for(j=1; j<=k; j++)
            if(i==j)
            {    
                hm=(i-i%(r*s))/r*s;
                if(hm==0)


Действительно, программа показала что ошибка в 76 строке - деление на 0. Оказалось, что r=0, хотя в 31 строке r=30 и больше вроде не меняется.

Хорошо, в след. раз буду создавать новые темы. 

P.S. И в каком разделе мне задавать вопросы типа "Как мне создавать и решать матрицы проводимостей для объектов размеров около 10000*1000*1000 узлов - никакой оп.памяти не хватит?"; "Где и как мне можно нарисовать объект, чтобы он автоматически мог затем рассчитываться в будущей моей программе?"

Автор: sergejzr 15.1.2007, 21:14
Модератор: Название темы должно отражать ее суть!

Автор: PandaRus 15.1.2007, 21:23
ОК. Извените. Сегодня ночью тема будет закрыта.
Только ответ получу на последние вопросы. Чтобы лишние темы не создавать.

Автор: PandaRus 15.1.2007, 21:53
После того, как подставил r=30 перед самим вычислением, программа запнулась на 87 строке - ошибка "нарушение доступа"

Автор: JackYF 16.1.2007, 16:11
Проверь границы массивов - у тебя там куча вложенных циклов, проверь выход индексов за рамки массива.

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