Ошибка Xcode: «EXC_BAD_ACCESS»

#c #xcode

#c #xcode

Вопрос:

Я пытаюсь скомпилировать и запустить программу на C в Xcode. Этой программе требуется текстовый файл для чтения входных данных и другой текстовый файл для записи данных. Я поместил программу и эти два текстовых файла в исходную папку. Программа успешно собрана, но при попытке запустить программу я получаю сообщение об ошибке: GDB: Программа получила сигнал: «EXC_BAD_ACCESS»

Что может быть причиной этого?

  int main() {

     FILE *fp; 
     FILE *fr;

     //Declare and intialize all variables to be used
     float ax = 0, ay = 0, x = 0, y = 0, vx = 0, vy = 0; 
     float time = 0, deltaTime = .001; 
     float timeImpact = 0, vyImpact = 0, vxImpact = 0, xImpact = 0, yImpact = 0; 

     int numBounces = 0;

     //Coefficient of Restitution; epsilon = ex = ey
     float ex = .5;
     float ey = .5;

     fr = fopen("input_data.txt", "rt"); //Open file for reading

     fp = fopen( "output_data.txt", "w" ); // Open file for writing

     if(fr == NULL){ printf("File not found");} //if text file is not in directory...

     if(fp == NULL){ printf("File not found");} //if text file is not in directory...

     fscanf(fr, "ax: %f ay: %f x: %f y: %f vx: %f vy: %fn", amp;ax, amp;ay, amp;x, amp;y, amp;vx, amp;vy); 

     while (time < 5) {

          //time = time   deltaTime
          time = time   deltaTime;
          //velocity[new] = velocity[old]   acc * deltaTime
          vx = vx   ax*deltaTime;
          vy = vy   ay*deltaTime;
          //position[new] = position[old]   velocity*deltaTime   .5*acc*(deltaTime)^2
          x = x   vx*deltaTime   (.5*ax*deltaTime*deltaTime);
          y = y   vy*deltaTime   (.5*ay*deltaTime*deltaTime);  

          //fprintf(fp, "%ft%ft%ft%ft%ft%ft%ftn", ax, ay, x, y, vx, vy, time);

               //Collision occurs; implement collision response
               if (y < 0) {

                  //Find time of collision by solving for t in equation vy*t   .5*ay*t^2   y = 0
                  timeImpact = (-vy   sqrt((vy*vy) - (2*ay*y)) / (2*.5*ay)); //Collision time = 3.7?

                  //velocity = -epsilon*velocity[Impact]   acc*time
                  vy = (-1*ey)*vyImpact   ay*((deltaTime - time) - timeImpact);
                  vx = (-1*ex)*vxImpact   ay*((deltaTime - time) - timeImpact);                            

                  //Position = position[Impact] - epsilon*velocity[Impact]*time   1/2*acc*time^2
                  x = xImpact - ex*vxImpact*((deltaTime - time) - timeImpact)   .5*ax*       ((deltaTime - time) - timeImpact) * ((deltaTime - time) - timeImpact);
                  y = yImpact - ey*vyImpact*((deltaTime - time) - timeImpact)   .5*ay*((deltaTime - time) - timeImpact) * ((deltaTime - time) - timeImpact);

                  //velocity = v[o]   ay(time)
                  vyImpact = vy   ay*(timeImpact - time);
                  vxImpact = vx   ax*(timeImpact - time); 

                  //position = position[o]   velocity(time)   1/2*acc*time^2
                  xImpact = x   vx*(timeImpact - time)   .5*ax*(timeImpact - time)*(timeImpact - time);  
                  //yImpact = y   vy*(timeImpact - time)   .5*ay*(timeImpact - time)*(timeImpact - time); 

                  numBounces  ; //Increment number of bounces ball takes

                  //fprintf(fp, "%ft%ft%ft%ft%ft%ft%ftn", ax, ay, x, y, vx, vy, time);
                  printf("timeImpact: %fnxImpact: %fnyImpact: %fnvxImpact: %fnvyImpact: %fn", timeImpact, xImpact, yImpact, vxImpact, vyImpact);
                  printf("Number of Bounce(s): %dnn", numBounces); 
               }
     }

     fclose(fp); //Close output file
     fclose(fr); //Close input file

     system ("PAUSE"); 
     return 0;
  }
  

Пример ввода:

ax: 0 ay: -9.8 x: 0 y: 50 vx: 8.66 vy: 5

Комментарии:

1. Если вы опубликуете свой код, возможно, мы сможем вам помочь…

2. Не могли бы вы добавить код, который вы используете, или строку, в которой отображается следующая ошибка

3. @MByD и @Swastik — я только что опубликовал код.

4. Я вставил код в Xcode, и, по-видимому, статический анализатор не обнаружил ошибок (учитывая, что вы включили stdio.h , stdlib.h и math.h ). Может быть, вы могли бы также опубликовать свой файл данных, чтобы я мог запустить полную программу.

5. @sidyll ax: 0 ay: -9.8 x: 0 y: 50 vx: 8.66 vy: 5

Ответ №1:

Программа работает почти правильно. Я получил этот вывод:

 timeImpact: 28.457277
xImpact: 7798.595703
yImpact: 0.000000
vxImpact: 315.561859
vyImpact: 73.370865
Number of Bounce(s): 1

timeImpact: -315.561096
xImpact: 984718.250000
yImpact: 0.000000
vxImpact: -3213.589600
vyImpact: 36.704834
Number of Bounce(s): 2

timeImpact: 3088.760254
xImpact: 94468824.000000
yImpact: 0.000000
vxImpact: 31913.345703
vyImpact: 55.056641
Number of Bounce(s): 3

timeImpact: -30290.189453
xImpact: 9086046208.000000
yImpact: 0.000000
vxImpact: -312763.843750
vyImpact: 45.875000
Number of Bounce(s): 4

timeImpact: 296834.687500
xImpact: 872571076608.000000
yImpact: 0.000000
vxImpact: 3065398.750000
vyImpact: 50.500000
Number of Bounce(s): 5

timeImpact: -2908993.750000
xImpact: 83802579795968.000000
yImpact: 0.000000
vxImpact: -30040802.000000
vyImpact: 48.000000
Number of Bounce(s): 6

timeImpact: 28507292.000000
xImpact: 8047926899113984.000000
yImpact: 0.000000
vxImpact: 294391936.000000
vyImpact: 64.000000
Number of Bounce(s): 7

timeImpact: -279371488.000000
xImpact: 772922520746590208.000000
yImpact: 0.000000
vxImpact: -2885036544.000000
vyImpact: 0.000000
Number of Bounce(s): 8

timeImpact: 2737840640.000000
xImpact: 74231486855715487744.000000
yImpact: 0.000000
vxImpact: 28273358848.000000
vyImpact: 0.000000
Number of Bounce(s): 9

timeImpact: -26831695872.000000
xImpact: 7129642377640744583168.000000
yImpact: 0.000000
vxImpact: -277087289344.000000
vyImpact: 0.000000
Number of Bounce(s): 10

timeImpact: nan
xImpact: nan
yImpact: 0.000000
vxImpact: nan
vyImpact: nan
Number of Bounce(s): 11

sh: PAUSE: command not found
  

Последняя строка может быть единственной проблемой. Что system("PAUSE") должен был делать?

EXC_BAD_ACCESS отображается в следующей строке:

 fscanf(fr, "ax: %f ay: %f x: %f y: %f vx: %f vy: %fn", amp;ax, amp;ay, amp;x, amp;y, amp;vx, amp;vy);
  

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

В Xcode выберите целевые объекты, а затем щелкните правой кнопкой мыши на вашей программе. Выберите пункт «Показать в Finder», который откроет папку, в которой находится программа. Поместите туда свой входной файл, и он должен сработать.


Для уточнения аргументов:

В вашей основной функции измените параметры, чтобы они соответствовали этому:

 int main (int argc, char *argv[])
  

Короче говоря, есть два параметра. Каждый исполняемый файл может получать аргументы при своем запуске, и эти параметры фиксируют эти аргументы. Например, рассмотрим, когда вы запускаете свою программу из командной строки:

 $ ./myprogram file1.txt file2.txt
  

file1.txt И file2.txt являются аргументами, они будут переданы в main . Основная функция имеет два аргумента: argc и argv . Первый — это int, содержащий количество аргументов, а второй — массив строк, самих аргументов.

В примере, который я привел, argc имеет значение 3, так как первым аргументом будет название программы (это небольшая деталь). Итак:

 argv[1] == "file1.txt"
argv[2] == "file2.txt"
  

Чтобы сделать это в Xcode, сначала измените свою основную функцию, чтобы она принимала параметры. Затем измените эту строку:

 fr = fopen("input_data.txt", "rt"); //Open file for reading
  

К этому:

 fr = fopen(argv[1], "rt"); //Open file for reading
  

Теперь, учитывая, что вы используете Xcode4, выберите пункт меню «Продукт> Редактировать схему …». В конфигурации запуска (боковая панель) выберите вкладку аргументы и добавьте путь к желаемому файлу ввода в разделе «Аргументы, переданные при запуске».

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

Теперь почитайте хорошую книгу по C и еще одну по Unix, в которых объясняются детали, которых я не делал 🙂

Комментарии:

1. Когда я щелкаю правой кнопкой мыши по целям, я не вижу опции «Показать в Finder».

2. @kachilous: Извините, я с головой ушел в Xcode 3. Откройте папку products, а затем щелкните правой кнопкой мыши на исполняемом файле в опции the.

3. @kachilous: Я рад, что это сработало. Что касается вашего последнего вопроса (о том, куда помещать текстовые файлы), исходный файл может быть где угодно. Просто будьте осторожны при указании пути. Если это просто имя файла, это означает, что файл должен находиться в том же месте, где находится исполняемый файл. Если вы хотите, чтобы файлы находились на вашем рабочем столе, продолжайте и укажите абсолютный путь в вашей программе, например /Users/{username}/Desktop/input_data.txt .

4. Итак, на будущее, любые текстовые файлы, от которых зависит программа, должны находиться в той же папке, что и исполняемый файл?

5. Если это относительный путь (только имя файла, как в вашем случае), тогда да. Но это действительно жесткое кодирование. Возможно, вы захотите взглянуть на аргументы, передаваемые функции main. При запуске вашей программы вы можете указать ей аргументы, используя один из них в качестве пути к желаемому файлу. Таким образом, имя файла и путь будут более «гибкими».

Ответ №2:

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

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