2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2, 3, 4  След.
 
 вопрос по си
Сообщение20.11.2017, 19:15 


18/05/15
733
Всем привет. Столкнулся с проблемой, к которой даже не знаю как подступиться. Обычная програмка на си. Определяется массив, элементам массива присваиваются значения, которые потом используются по очереди в цикле. Каким-то мистическим для меня образом значения элементов массива, начиная с какого-то номера, меняются, конкретно обнуляются. Мистическим, потому что никаких новых присвоений внутри цикла нет. Не подскажите в каком напралении копать, чтобы докопаться до причины? Заранее благодарен

 Профиль  
                  
 
 Re: вопрос по си
Сообщение20.11.2017, 19:25 
Заслуженный участник
Аватара пользователя


16/07/14
9213
Цюрих
Не знаю, что такое "конкретно обнуляется", но выглядит как типичный выход за границы массива где-то. Скомпилируйте с address sanitizer'ом для начала.

 Профиль  
                  
 
 Re: вопрос по си
Сообщение20.11.2017, 19:28 
Заслуженный участник
Аватара пользователя


06/10/08
6422
Ну поскольку никаких деталей программы Вы не предоставили, то можно дать только самый общий совет: сначала включаете все доступные средства статического анализа и смотрите, не выдают ли они что-нибудь полезное, а если не помогло, то берете отладчик, находите точно оператор, на котором обнуляется то, что не нужно, замечаете значения всех используемых переменных и пытаетесь понять, почему этот оператор при этих значениях лезет куда не надо.

 Профиль  
                  
 
 Re: вопрос по си
Сообщение20.11.2017, 19:59 


18/05/15
733
mihaild, выхода за границы нет. Массив $A$ из $N$ элементов, и цикл $for$ от $0$ до $N-1$. Более того, чтобы не обращаться больше к массиву внутри цикла, я присваиваю $a = A[i]$ и всё, дальше во всех выражениях только $a$. И вот, когда $N$ нечётное, то после завершения цикла $A[i] = 0$ для всех $i>N/2$. Если $N$ чётное, всё нормально, с элементами массива ничего не происходит, как и должно быть по идее.

Xaositect спасибо за ключевое слово отладчик:) А то я в гугле уже и так пробовал сформулировать и этак..

 Профиль  
                  
 
 Re: вопрос по си
Сообщение20.11.2017, 20:38 
Заслуженный участник


09/05/12
25179
По-видимому, код все-таки не настолько большой, что его нельзя привести полностью. Так что выложите, посмотрим.

 Профиль  
                  
 
 Re: вопрос по си
Сообщение20.11.2017, 21:55 
Заслуженный участник


20/08/14
11867
Россия, Москва
Смахивает на опечатку, где-то вместо "==" стоит "=" ... Нужен код.

 Профиль  
                  
 
 Re: вопрос по си
Сообщение20.11.2017, 22:47 


18/05/15
733
Параметры для ввода: $Q$ и $nR$. Первый параметр - это степень двойки; $N=2^Q$ - размер решетки $N \times N \times N$, можно присвоить $Q=8$. Второй параметр $nR$ - количество лучей. Если число $nR$ чётное, всё нормально, а если нет, возникает проблема, которую я попытался описать в стартовом посте. И всё из-за того, что неправильно задана длина nP массивов ind_1 и ind_2. Сейчас в коде nP = 3*N. Это мало. На сам деле должно быть 4*N.

О коде. Это быстрый алгоритм поиска узлов решетки, рассположенных на расстоянии <d от линии луча с фокусом в (xF,yF,zF) и направляющим вектором $tau$

код: [ скачать ] [ спрятать ]
Используется синтаксис C
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#define RDFLAG O_RDONLY
#define RWFLAG O_RDWR

#define PI 3.141592653589
#define FOD 3.0

int main (int argc, char **argv)
{
  int Q, nR;
  int i,j;
  i = 1;
  while (i < argc)
    {
      if (strcmp(argv[i], "-Q")==0)
           Q = atol(argv[++i]);
      else if (strcmp(argv[i], "-nR")==0)
           nR = atol(argv[++i]);
      i++;
    }
 
  long N, NN;
  N = 1<<Q;
  NN = N*N;
       
  short *B0;
  short *B1;
  B0 = malloc(sizeof(short)*N*N*N);
  B1 = malloc(sizeof(short)*N*N*N);
  for(i=0; i<N*N*N; i++){
    B0[i] = 0;
    B1[i] = 0;
  }
 
  float xF, yF, zF;
  xF = FOD*N;
  yF = 0.0;
  zF = 0.0;

  float nFF;
  nFF = (xF*xF + yF*yF + zF*zF);

  short px[8] = {-1,-1,-1,-1,1,1,1,1};
  short py[8] = {-1,-1,1,1,-1,-1,1,1};
  short pz[8] = {-1,1,-1,1,-1,1,-1,1};
 
  short sx[8] = {0,0,0,0,2,2,2,2};
  short sy[8] = {0,0,2,2,0,0,2,2};
  short sz[8] = {0,2,0,2,0,2,0,2};

  double a, aa;
  aa = 3.0*1.00394*1.00394;
  a = sqrt(aa);

  short *qK;
  long *qS;
  double *qR;
  qS = malloc(sizeof(long)*Q);
  qR = malloc(sizeof(double)*Q);
  qK = malloc(sizeof(short)*Q);

  int q, coef;
  for(q=0;q<Q;q++){
    coef = 1<<(Q-q-1);
    qS[q] = coef;
    qR[q] = a*coef;
    qK[q] = -1;
  }

  int *xseed;
  int *yseed;
  int *zseed;
  xseed = malloc(sizeof(int)*Q);
  yseed = malloc(sizeof(int)*Q);
  zseed = malloc(sizeof(int)*Q);

  xseed[0] = 0;
  yseed[0] = 0;
  zseed[0] = 0;
 
  int nP;
  nP = 3*N;

  int *ind_0;
  int *ind_1;
  ind_0 = malloc(sizeof(int)*nP);
  ind_1 = malloc(sizeof(int)*nP);

  int ir0, ir1;
  for(j=0;j<nP;j++){
    ind_0[j] = -1;
    ind_1[j] = -1;
    }

  float *tau_x;
  float *tau_y;
  float *tau_z;
  tau_x = malloc(sizeof(float)*nR);
  tau_y = malloc(sizeof(float)*nR);
  tau_z = malloc(sizeof(float)*nR);

  printf("before:\n");
  float t;
  for(j=0; j<nR; j++){
    t = -0.5 + (j+0.5)/nR;
    tau_x[j] = sqrt(1.0-t*t);
    tau_y[j] = t;
    tau_z[j] = 0.0;
    printf("%d: %f,%f,%f\n", j, tau_x[j],tau_y[j], tau_z[j]);
  }

  short k;
  int nx, ny, nz;
  float r, rr, dd, tt, tx, ty, tz, taux, tauy, tauz, tauF, test;

  printf("\n");
  printf("in loop:\n");
  for(j=0; j<nR; j++){
    ir0 = 0;
    ir1 = 0;

    taux = tau_x[j];
    tauy = tau_y[j];
    tauz = tau_z[j];
    printf("%d: %f,%f,%f\n", j, tau_x[j],tau_y[j], tau_z[j]);
    tauF = taux*xF + tauy*yF + tauz*zF;
   
    test = nFF-tauF*tauF;
    if (test < NN){
 
      q = 0;
      while(1){
        r = qR[q];
        rr = r*r;
        dd = rr;
        k = qK[q];

        while(k<7 && dd>=rr){
          k+=1;
          nx = xseed[q] + px[k]*qS[q];
          ny = yseed[q] + py[k]*qS[q];
          nz = zseed[q] + pz[k]*qS[q];

          tx = nx-xF;
          ty = ny-yF;
          tz = nz-zF;

          tt = tx*taux + ty*tauy + tz*tauz;
          dd = (tx-tt*taux)*(tx-tt*taux) + (ty-tt*tauy)*(ty-tt*tauy) + (tz-tt*tauz)*(tz-tt*tauz);
        }

        if(dd < rr){
          qK[q] = k;
          q+=1;
          xseed[q] = nx;
          yseed[q] = ny;
          zseed[q] = nz;

        }else{
          qK[q] = -1;
          q-=1;
        }
       
        if (q == (Q-1)){
         
          for(i=0;i<8;i++){
            nx = xseed[q] + sx[i];
            ny = yseed[q] + sy[i];
            nz = zseed[q] + sz[i];

            if(nx*nx+ny*ny+nz*nz < NN){
              tx = nx-xF;
              ty = ny-yF;
              tz = nz-zF;

              tt = tx*taux + ty*tauy + tz*tauz;
              dd = (tx-tt*taux)*(tx-tt*taux) + (ty-tt*tauy)*(ty-tt*tauy) + (tz-tt*tauz)*(tz-tt*tauz);
     
              if(dd<aa){
                nx = (N+nx)>>1;
                ny = (N+ny)>>1;
                nz = (N+nz)>>1;
                ind_0[ir0] = nz*NN+ny*N+nx;
                ir0+=1;
              }
            }
          }
          for(i=0;i<8;i++){
            nx = xseed[q] + px[i];
            ny = yseed[q] + py[i];
            nz = zseed[q] + pz[i];

            if(nx*nx+ny*ny+nz*nz<NN){
              tx = nx-xF;
              ty = ny-yF;
              tz = nz-zF;

              tt = tx*taux + ty*tauy + tz*tauz;
              dd = (tx-tt*taux)*(tx-tt*taux) + (ty-tt*tauy)*(ty-tt*tauy) + (tz-tt*tauz)*(tz-tt*tauz);
           
              if(dd<aa){      
                nx = (N+nx)>>1;
                ny = (N+ny)>>1;
                nz = (N+nz)>>1;
                ind_1[ir1] = nz*NN+ny*N+nx;
                ir1+=1;
              }
            }
          }
          qK[q]=-1;
          q-=1;
        }//if q == Q-1

        if(q == -1)
          break;
      }//while(1)
     
/*
      for (i=0;i<ir0;i++)
        B0[ind_0[i]] = 1;
      for (i=0;i<ir1;i++)
        B1[ind_1[i]] = 1;
      int unit;
      unit=open("image",RWFLAG|O_CREAT|O_TRUNC|O_APPEND,S_IREAD|S_IWRITE);
      if(unit == -1){
        printf("Cannot open file %s\n","image");
        exit(1);
      }
      write(unit, B0, sizeof(short)*N*N*N);
      write(unit, B1, sizeof(short)*N*N*N);
*/

    }
  }
  printf("\n");
  printf("after:\n");
  for(j=0; j<nR; j++)
    printf("%d: %f,%f,%f\n", j, tau_x[j],tau_y[j], tau_z[j]);
    }
 

 Профиль  
                  
 
 Re: вопрос по си
Сообщение20.11.2017, 23:01 
Заслуженный участник
Аватара пользователя


16/07/14
9213
Цюрих
То, что вы выложили, не компилируется (и не может - у вас там забыта скобока и не объявлена переменная aa). Выложите сюда или на pastebin код, который запускаете, и укажите параметры запуска.

(Оффтоп)

Выкладывать код в формате docx - очень странная идея.

 Профиль  
                  
 
 Re: вопрос по си
Сообщение20.11.2017, 23:30 
Заслуженный участник


09/05/12
25179
Да уж. Несколько мелких дефектов, вроде забытых скобок и точек с запятой, забытые объявления переменных, ну и в целом код ужасен.

 Профиль  
                  
 
 Posted automatically
Сообщение20.11.2017, 23:32 
Заслуженный участник


09/05/12
25179
 i  Тема перемещена из форума «Программирование» в форум «Карантин»
по следующим причинам:

- проверьте код на минимальную синтаксическую корректность;
- вставьте код нормально (см.совет выше или прямо в сообщение с подсветкой синтаксиса и в тэге оффтопика), результаты также вставьте в текстовом виде;

Исправьте все Ваши ошибки и сообщите об этом в теме Сообщение в карантине исправлено.
Настоятельно рекомендуется ознакомиться с темами Что такое карантин и что нужно делать, чтобы там оказаться и Правила научного форума.

 Профиль  
                  
 
 Posted automatically
Сообщение22.11.2017, 14:35 
Заслуженный участник


09/05/12
25179
 i  Тема перемещена из форума «Карантин» в форум «Программирование»

 Профиль  
                  
 
 Re: вопрос по си
Сообщение22.11.2017, 14:49 
Заслуженный участник
Аватара пользователя


16/07/14
9213
Цюрих
А в чем вопрос-то? Ну да, вы обращаетесь к ind_1 по индексу большему чем его размер. При этом может произойте всё что угодно (undefined behavior), в данном случае происходит еще вполне разумная вещь - меняется массив, идущий дальше. Что не так?

 Профиль  
                  
 
 Re: вопрос по си
Сообщение22.11.2017, 14:51 
Заслуженный участник


20/08/14
11867
Россия, Москва
Раз обещал, расскажу коротко как искал ошибку в исходном коде.
Для начала разумеется исправил опечатки и дообъявил пропущенные переменные, присвоив им типы и значения "примерно по смыслу". Потом убрал ввод параметров и объявил их константами (тоже весьма приблизительными т.к. выискивать их смысл по исходнику было лень, а автор комментариев не оставил). Стал вставлять выход из функции main после каждого цикла и проверять возникают ли ошибки. Оказалось возникают. Тогда переделал все (чтобы "два раза не вставать") массивы на статические, пришлось некоторые константы задать дефайнами. Всё, этого оказалось достаточно для отсутствия ошибок. Из этого был сделан вывод что ошибка таки в выходе за пределы массива. Где именно - не искал. Как это связано с увеличением размеров массивов ind мне непонятно, возможно это проблема в использованном мною компиляторе (что программа отработала без ошибок без изменения размеров массивов).
Под ошибкой понимаю лишь вылет программы с ненулевым кодом возрата или по ошибке вычислений или зануление конца выводимого массива. Корректность самих выводимых чисел никак не проверялась.

-- 22.11.2017, 14:53 --

mihaild в сообщении #1267965 писал(а):
А в чем вопрос-то?
Кажется уже ни в чём, последнее сообщение ТС поправлено и там уже сказано что ошибка найдена. До попадания в Карантин она найдена не была. ;-)

 Профиль  
                  
 
 Re: вопрос по си
Сообщение22.11.2017, 15:00 
Заслуженный участник
Аватара пользователя


16/07/14
9213
Цюрих
Dmitriy40, на случай если вы про него не знаете - существует AddressSanitizer, очень сильно упрощающий поиск таких проблем (есть еще конечно valgrind, он мощнее но гораздо менее удобен).

 Профиль  
                  
 
 Re: вопрос по си
Сообщение22.11.2017, 15:18 
Заслуженный участник


20/08/14
11867
Россия, Москва
Спасибо, да, не знаю. Ой, там про винду молчат ... Но всё равно полезно.

(Оффтоп)

Но у меня обычно таких проблем и нет. А если и есть - то (опять же обычно) на ассемблере. И часто - не под комп. Так что отладчик и осциллограф всегда под рукой. :-)

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 46 ]  На страницу 1, 2, 3, 4  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group