Что делает мой код недетерминированным? - PullRequest
2 голосов
/ 19 ноября 2010

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

Возможно ли на стороне компилятора, что мой тот же код переделан таким образом, что он вообще не работает?

Я запускаю .exe, просто нажимая на него, и он работает нормально, но когда я нажимаю «Скомпилировать и запустить» (Dev C ++ 4.9.9.2), ни одно из моих изображений не получается правильным.... хотя иногда они делают.

... есть понимание, как это исправить?Если я могу оказать дополнительную помощь, пожалуйста, скажите мне.

Многое оценено.

Редактировать: Вот блок кода, который, если я его закомментирую, все будет работать как надо.(Это полностью детерминировано, если я закомментирую этот блок) - это электромагнитный симулятор, если это вообще помогает:

        //***********************************************************************
    //     Update HZ in PML regions (hzx,hzy)
    //***********************************************************************

    boundaryIndex = 0;
    for (regionIndex = 1; regionIndex < NUMBEROFREGIONS; regionIndex++) {
        xStart = regionData[regionIndex].xStart;
        xStop  = regionData[regionIndex].xStop ;
        yStart = regionData[regionIndex].yStart;
        yStop  = regionData[regionIndex].yStop ;
        for (i = xStart; i < xStop; i++) {
            for (j = yStart; j < yStop; j++) {
                hzx = hz[i*xSize+j] - hzy[boundaryIndex];   // extract hzx
                hzx = dahz[i*xSize+j] * hzx + dbhz[i*xSize+j] * ( ey[i*(xSize+1)+j] - ey[(i+1)*(xSize+1)+j] );    // dahz,dbhz holds dahzx,dbhzx
                hzy[boundaryIndex] = dahzy[boundaryIndex] * hzy[boundaryIndex] + dbhzy[boundaryIndex] * ( ex[i*ySize+j+1] - ex[i*ySize+j] );
                hz[i*xSize+j] = hzx +  hzy[boundaryIndex];  // update hz
                boundaryIndex++;
            }  //jForLoop /
        }  //iForLoop /
    }  //

где, NUMBEROFREGIONS является константой (8), Xsize определяется во время компиляции (128здесь).

Ответы [ 5 ]

4 голосов
/ 19 ноября 2010

Ну, некоторые примеры кода помогут!Но это классический признак неинициализированных переменных.

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

3 голосов
/ 19 ноября 2010

Есть ли ошибка индексации с вашим симулируемым двумерным массивом?ey должен иметь ширину xSize или xSize + 1?

   dahz[i*xSize+j] * hzx +
   dbhz[i*xSize+j] * ( ey[i*(xSize+1)+j] - 
   ey[(i+1)*<b>(xSize+1)</b>+j] ); 

Ваш индекс рассматривает двумерный массив ey как ширину xSize + 1.Код для массива ex обрабатывает его как ширину ySize.

 dbhzy[boundaryIndex] * ( ex[<b>i*ySize+j+1</b>] - ex[i*ySize+j] );
2 голосов
/ 19 ноября 2010

Вы потенциально вызываете неопределенное поведение. Есть ряд вещей, которые не определены стандартом языка C. Некоторые из этих случаев могут быть обнаружены компилятором, и вам может быть выдано диагностическое сообщение, другие сложнее поймать компилятором. Вот несколько вещей с неопределенным поведением:

  1. Попытка использовать значение неинициализированной переменной:

    int i;
    printf("%d\n", i); // could be anything!
    
  2. Объект изменяется более одного раза между точками последовательности:

    int i = 4;
    i = (i += ++i); // Woah, Nelly!
    
  3. Чтение или запись после конца выделенного блока памяти:

    int *ints = malloc(100 * sizeof (int));
    ints[200] = 0; // Oops...
    
  4. Использование printf et. но с указанием неверных спецификаторов формата:

    int i = 4;
    printf("%llu\n", i);
    
  5. Преобразование значения в целочисленный тип со знаком, но тип не может представлять значение (некоторые говорят, что это определяется реализацией, а спецификация языка C кажется неоднозначной):

    signed short i;
    i = 100.0 * 100.0 * 100.0 * 100.0; // probably won't fit
    

Edit:

Ответ перед тем, как OP предоставил код.

1 голос
/ 19 ноября 2010

Как все говорили без кода, что не так, мы не можем вам сильно помочь.

Мой лучший жест из того, что вы только что объяснили, заключается в том, что вы создаете указатели на нераспределенной памяти.

как то так

APointer *aFunction(){
   YourData yd = something;//local variable creation
   return yd;
}

main(){

APointer *p = aFunction();

}

Здесь p - указатель на то, что было локальным переменным в aFunction и было уничтожено, как только оно вышло из функции, когда-нибудь PURE LUCK по-прежнему будет указывать на правильные данные, которые не были записаны, но это пространство памяти будет в конечном итоге изменено, и ваш указатель будет читать что-то совершенно случайное.

1 голос
/ 19 ноября 2010

Вы компилируете его в режиме отладки или в режиме выпуска? У каждого из них есть свой способ инициализации кучи и памяти.

...