I am attempting to compile and run a C program in Xcode. This program requires a text file for reading input and another text file for writing the data. I have put the program, and these two text files in the Source folder. The program builds successfully, but when I try to run the program I get the error: GDB: Program received signal: “EXC_BAD_ACCESS”
What could be causing this?
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: %f\n", &ax, &ay, &x, &y, &vx, &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, "%f\t%f\t%f\t%f\t%f\t%f\t%f\t\n", 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, "%f\t%f\t%f\t%f\t%f\t%f\t%f\t\n", ax, ay, x, y, vx, vy, time);
printf("timeImpact: %f\nxImpact: %f\nyImpact: %f\nvxImpact: %f\nvyImpact: %f\n", timeImpact, xImpact, yImpact, vxImpact, vyImpact);
printf("Number of Bounce(s): %d\n\n", numBounces);
}
}
fclose(fp); //Close output file
fclose(fr); //Close input file
system ("PAUSE");
return 0;
}
Sample Input:
ax: 0 ay: -9.8 x: 0 y: 50 vx: 8.66 vy: 5
The program works almost properly. I got this output:
The last line might be the only problem. What the
system("PAUSE")was supposed to do?EXC_BAD_ACCESS appears in the following line:
Setting a breakpoint in it showed that
frwas NULL, and that’s the problem. The path to the files were set relatively to the executable location, but notice that the executable goes to a build folder, which does not contain the input and output files (these are located in your project folder).In Xcode, select targets and then right click on your program. Choose the “Show in Finder” item, which will open a folder where the program is located. Drop your input file there and it should work.
To clarify the arguments:
In your main function, change the parameters to match this:
In short, there are two parameters. Every executable can receive arguments on its launch, and these parameter capture those arguments. For example, consider when you launch your program from the command line:
The
file1.txtandfile2.txtare arguments, they will be passed to main. The main function has two arguments:argcandargv. The first is an int, holds the number of arguments, and the second is an array of strings, the arguments themselves.In the example I gave,
argcis set to 3, as the first argument will be the program name (that’s a little detail). So:To do it in Xcode, first modify your main function to accept parameters. Then, modify this line:
To this:
Now, considering you’re on Xcode4 choose the “Product > Edit Scheme…” menu item. In the run configuration (side bar), choose the arguments tab and add a path to the desired input file in the “Arguments passed on Launch” section.
That’s it. Your program will now run as before, but when you need to use another file, you don’t need to recompile the program. Just change the path in the argument list. This may appear to be more work, but once you have larger programs and starting using the command line, it will make more sense.
Now go read a good book on C and another on Unix that explain the details I didn’t 🙂