I am doing my homework to realize a C programe and during my work there is one step that I need to get the interger part of the double type numbers. So I choose ceil() or floor() in to realize this. But the output is unpredictable and far from expected.
The whole program is the following :
/*
************************************************************************
Includes
************************************************************************
*/
#include <stdio.h>
#include <stdlib.h>
#include <gsl/gsl_rng.h>
#include <time.h>
#include <math.h>
/* Solvent Particle Propersities*/
typedef struct
{
double vx,vy,rx,ry ; /* velocity AND position */
double cell; /* index of grid */
}solvent_p;
/* Cell Propersities*/
typedef struct
{
double vcm_x,vcm_y ; /* center of mass velocity */
int number; /* number of solvent in the cell */
double roation_angle; /* roation_angle of the cell */
}cell_p;
/* periodic boundary condition judging and adjusting fuction PBC */
void PBC(solvent_p *sol)
{
double L = 20.0; // box size 20
if(sol->rx >20) sol->rx=sol->rx-L;
if(sol->rx < 0) sol->rx=sol->rx+L;
if(sol->ry >20) sol->ry=sol->ry-L;
if(sol->ry < 0) sol->ry=sol->ry+L;
}
int main(int argc, char **argv)
{
// Randome setup generates random numbers from GSL functions
const gsl_rng_type * T;
gsl_rng * r;
T = gsl_rng_default;
gsl_rng_default_seed = ((unsigned long)(time(NULL))); //设seed值为当前时间
r = gsl_rng_alloc (T);
solvent_p solvent[4000];
int i,j,k,index=0;
cell_p grid[400];
double alpha=90.0; //roation angle
/* Iniinitializing solvent
* All vx=0
* half vy = sqrt(3) and half vy=-sqrt(3) to make momentum zero and another requirement is the overall energy is 6000 equals energy of temperature=1 with 4000 solvent 3NkT/2 ,assuming mass of solvent = 1 ,which is all a test quantity
* rx and ry are random number generated by GSL library
* cell=20*(ry+rx) is an index of which cell the solvent is in
*/
for(i=0;i<=3999;i++)
{
solvent[i].vx=0.0;
if(i<=1999)
solvent[i].vy=sqrt(3);
else
solvent[i].vy=-sqrt(3);
solvent[i].rx =20.0 * gsl_rng_uniform_pos(r);
solvent[i].ry =20.0 * gsl_rng_uniform_pos(r);
//printf("%f \t %f \n",solvent[i].rx,solvent[i].ry);
solvent[i].cell=20*(floor(solvent[i].ry))+floor(solvent[i].rx)+1;
}
// grid setting up
for (i=0;i<=399;i++)
{
grid[i].vcm_x=0;
grid[i].vcm_y=0;
grid[i].number=0;
grid[i].roation_angle=0.0;
}
/* Begining Simulation Work
*
* Fist process is preparing the system to equilibrium for 10000 processes
*
* the whole process involving two steps steaming and collision and the two steps are conducted one by one in our simulation
* time duration for steaming is 0.1 which is assigned for Molecular Dynamics and time duration for collision is ignored
*
*
*/
for(i=0;i<=9999;i++)
{
double temp;
double delta_t_MD=0.1; //time step
temp=gsl_rng_uniform_pos(r);
double rand_rx = (temp < 0.5) ? temp : ((-1) * temp ); // randomshift rx;
temp=gsl_rng_uniform_pos(r);
double rand_ry = (temp < 0.5) ? temp : ((-1) * temp ); // randomshift ry
//steaming
for(j=0;j<=3999;j++)
{
//printf("%d \n",j);
printf("1 :%d \t %f \t %f \n",j,solvent[j].rx,solvent[j].ry);
solvent[j].rx=solvent[j].rx+solvent[j].vx * delta_t_MD;
solvent[j].ry=solvent[j].ry+solvent[j].vy * delta_t_MD;
printf("2: %d \t %f \t %f \n",j,solvent[j].rx,solvent[j].ry);
//randomshift
solvent[j].rx=solvent[j].rx+rand_rx;
solvent[j].ry=solvent[j].ry+rand_ry;
printf("3: %d \t %f \t %f \n",j,solvent[j].rx,solvent[j].ry);
// periodic boundary condition
PBC(&solvent[j]);
printf("4: %d \t %f \t %f \n",j,solvent[j].rx,solvent[j].ry);
solvent[j].cell=20*(ceil(solvent[j].ry)-1)+ceil(solvent[j].rx);
printf("5: %d \t %f \t %f \t %f \t %f \n",j,solvent[j].rx,solvent[j].ry,ceil(solvent[j].rx),ceil(solvent[j].ry));
index = (int)(solvent[j].cell);
//printf("%d \t %d \t %f \t %f \t %f \n",j,index,solvent[j].cell,ceil(solvent[j].rx),ceil(solvent[j].ry));
if ((index>=0) &&(index<=400))
{
grid[index].vcm_x=grid[index].vcm_x+solvent[i].vx;
grid[index].vcm_y=grid[index].vcm_y+solvent[i].vy;
grid[index].number=grid[index].number+1;
}
}
// caculating vcm
for (k=0;k<=399;k++)
{
if (grid[k].number >= 1)
{
grid[k].vcm_x=grid[k].vcm_x/grid[k].number;
grid[k].vcm_y=grid[k].vcm_y/grid[k].number;
}
double temp;
temp=gsl_rng_uniform_pos(r);
grid[k].roation_angle = (temp < 0.5) ? alpha : ((-1) * alpha );
}
//collsion
}
gsl_rng_free (r); // free RNG
return 0;
}
Sorry it is some extent long so I did not put in first.And something did not finished but the program framework is set up.
my programe is like this:
printf("4: %d \t %f \t %f \n",j,solvent[j].rx,solvent[i].ry);
solvent[j].cell=20*(floor(solvent[j].ry))+floor(solvent[j].rx)+1;
printf("5: %d \t %f \t %f \t %f \t %f \n",j,solvent[j].rx,solvent[i].ry,floor(solvent[j].rx),floor(solvent[j].ry));
And although something as I wanted something more is wrong and below is I choose some parts of the output:
4: 3993 3.851240 17.047031
5: 3993 3.851240 17.047031 3.000000 9.000000
although floor(solvent[j].rx) is right but floor(solvent[j].ry) is totally wrong.
And the final result of my program is
Segmentation fault (core dumped)
------------------
(program exited with code: 139)
How to fix this one? Is there anything I use was wrong?
And to further test the problem I tried ceil() function in and the program and result is like this
program:
printf("4: %d \t %f \t %f \n",j,solvent[j].rx,solvent[i].ry);
solvent[j].cell=20*(ceil(solvent[j].ry)-1)+ceil(solvent[j].rx);
printf("5: %d \t %f \t %f \t %f \t %f \n",j,solvent[j].rx,solvent[i].ry,ceil(solvent[j].rx),ceil(solvent[j].ry));
result:
2: 3999 14.571205 2.837654
4: 3999 14.571205 2.837654
5: 3999 14.571205 2.837654 15.000000 15.000000
So use the nearest output as an example to illustrate my desire result is:
a= 14.571205, ceil(a)=15.00
b= 2.837654 , ceil(b)=3.00 not the 15.000 in the output
And the problem worsening is that when I just use a and b to test ceil() everything seems perfect:
program:
#include <stdio.h>
#include <math.h>
int main()
{
double a= 14.571205;
double b= 2.837654 ;
printf("%f \t %f \n",ceil(a),ceil(b));
return 0;
}
output:
15.000000 3.000000
I am using GCC in Linux Ubuntu.
==============================================================================
The problem has been solved.
The real fatal problem is here
if ((index>=0) &&(index<=400))
{
grid[index].vcm_x=grid[index].vcm_x+solvent[i].vx;
grid[index].vcm_y=grid[index].vcm_y+solvent[i].vy;
grid[index].number=grid[index].number+1;
}
}
Both solvent[i].vy and solvent[i].vx should be changed i for j.
Just as #Jon and #Blckknght #Eric Lippert have pointed out.
And I obvious get in the wrong trap and mislead #ouah and #Blckknght and In fact, the output sentences do have problem but they do not caused the prorame to crash only the out of boundary will do that.
Thank you ALL!
And I do like to share Eric Lippert 's comment which is powerful and insightful:
More generally, the problem you have is called "select isn't broken" by experienced programmers. That is, you have done something completely wrong, you cannot figure out what you did wrong, and so you conclude that a piece of basic, easy infrastructure written by experts and tested extensively is wrong. I assure you, floor and ceil do exactly what they are supposed to do. They are not wrong. The problem lies somewhere in your code, not in the standard library. – Eric Lippert
Your array is declared as:
solvent_p solvent[4000];
but you have this loop:
for(i=0;i<=9999;i++)
with this function call inside:
printf("1 :%d \t %f \t %f \n",j,solvent[j].rx,solvent[i].ry);
which means you are accessing out-of-bounds array elements.
EDIT:
OP test case has been edited to fix the out-of-bound accesses.
My second suggestion is to check index value (which is used to index grid array) never exceeds the number of elements of grid array after this assignment: index = (int)(solvent[j].cell).
I'm pretty sure the issue is with the indexes you're using. In the statement in question:
printf("5: %d \t %f \t %f \t %f \t %f \n",j,solvent[j].rx,solvent[i].ry,floor(solvent[j].rx),floor(solvent[j].ry));
you are printing the ry value of solvent[i] but the floor of the ry value of solvent[j]. I suspect that you want to be using the same index in both places (though I'm not sure which index you want).
Related
I have 63 .txt file with 26 headers lines and then 19 columns of float data.
I would like to read all the files and store (in row) the first 6 columns of the .txt files (x,y,z,u,v,w). Then for each .txt file I would like to append these data in a new row.
This is the code that I did but after the first j (j=1) then the script crash because the sizes of the arrays are not the same, indeed for some reasons during the first iteration it is skipping not 26 but 52 lines (so also the first 26 of numbers that I want), while in the second is (in a correct way skiiping only 26 headers line).
inpDir = "\\ftac\Folder\CD";
files = dir(fullfile(inpDir, '*.txt'));
n_file = size(files,1);
for j=1:n_file
fid = fopen(files(j).name, 'r');
data = textscan(fid, '%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f', 'HeaderLines', 26, 'Delimiter',' ');
fclose(fid);
x(j, :) = data{1}'; % x coordinate
y(j, :) = data{2}'; % y coordinate
z(j, :) = data{3}'; % y coordinate
u(j, :) = data{4}';% u velocity
v(j, :) = data{5}'; % v velocity
w(j, :) = data{6}'; % w velocity
end
How can I solve this issue? Thanks in advance
I am working to learn about computing at a more granular level and have started studying both Linux and C at the same time. Smooth sailing until just now.
I am running Linux Mint 17 on Kernel 3.16.0-38-generic and using Code::Blocks 13.12 as my IDE.
The following pastes are my practice code using data types, variables, and printf(), and the associated output I see in a vt -- the oddity I see is that on my experimentation with decimal places using the float data type, it seems to be skipping values after the 5th and eventually 4th decimal place.
Am I abusing the process of calling a variable, am I missing a bug in my code, or is this a bug in CodeBlocks? Also -- I'm not sure why my code snippet is completely mashed together in the preview, so my apologies for the poor readability
code to be compiled and executed:
/* Prints a message on the screen */
#include <stdio.h>
echar a1 = 'a';
int i1 = 1;
float f1 = 0.123456;
int main()
{
printf("Testing %c la%sof characters using variables \n", a1, "rge string " );
printf("This line has the values %d and %f.\n", i1, f1);
printf("%f can also be displayed as %.5f or %.4f or %.3f or %.2f or %.1f or %.0f \n",
f1, f1, f1, f1, f1, f1, f1);
printf("Which is an integer . . .");
return 0;
}
output of compiled and executed code
Testing a large string of characters using variables
This line has the values 1 and 0.123456.
0.123456 can also be displayed as 0.12346 or 0.1235 or 0.123 or 0.12 or 0.1 or 0
Which is an integer . . .
Process returned 0 (0x0) execution time : 0.002 s
Press ENTER to continue.
Thank you for any help you can provide. I am studying from C Programming Absolute Beginner - by Greg Perry
As was mentioned in the comments, the last digit is being rounded.
If you had this:
float f1 = 0.777777;
The output would be this:
This line has the values 1 and 0.777777.
0.777777 can also be displayed as 0.77778 or 0.7778 or 0.778 or 0.78 or 0.8 or 1
Similarly, if you had this:
float f1 = 0.999888;
You'd get this:
This line has the values 1 and 0.999888.
0.999888 can also be displayed as 0.99989 or 0.9999 or 1.000 or 1.00 or 1.0 or 1
This is the piece of code I have which prints my diffused density matrices to a file after every nth time step of the simulation time given by fdparam_1.t_domain. t and fdparam_1.Dt are variables of the type double. All variables are declared and defined either with user input or with pre-defined values in the code.
Please note that the last time I posted the code for the segmentation fault, I modified the code as per the suggestions and this piece of code below is the modified one, although the operations are obviously the same.
int main(void)
{
int i,j,size,sz;
double *ux, *vy, *ux0, *vy0, *r, *r0, t, sum, sum1;
struct fdparam fdparam_1;
printf("Enter the number of grid points: \t");
scanf("%d", &fdparam_1.N);
printf("Enter the maximum number of iterations: \t");
scanf("%d", &fdparam_1.MAXIT);
printf("Enter the value for time domain and the time interval: \t");
scanf("%d\t%d", &fdparam_1.t_domain, &fdparam_1.Del_t);
printf("Enter the time step, number of molecules: \t \t");
scanf("%lf\t%lf", &fdparam_1.Dt, &fdparam_1.dens);
printf("Enter the volume of the fluid: \t");
scanf("%lf", &fdparam_1.V);
printf("Enter the diffusion coefficient and viscosity and angular velocity(in rad/s): \t \t");
scanf("%lf\t%lf\t%lf",&fdparam_1.diff, &fdparam_1.mu, &fdparam_1.wv);
size=(fdparam_1.N+2)*(fdparam_1.N+2);
sz=fdparam_1.t_domain/fdparam_1.Del_t;
double map[fdparam_1.N+2][fdparam_1.N+2],map_init[fdparam_1.N+2][fdparam_1.N+2],n_calc, time[sz+1];
r = (double*) calloc (size,sizeof(double));
r0 = (double*) calloc (size,sizeof(double));
ux = (double*) calloc (size,sizeof(double));
vy = (double*) calloc (size,sizeof(double));
ux0 = (double*)calloc (size,sizeof(double));
vy0 = (double*)calloc (size,sizeof(double));
double vol = fdparam_1.V;
FILE *fp1[sz+1];
var_init(fdparam_1.N,r0,ux0,vy0,fdparam_1.dens);
sum1=r0[0];
for (i=0;i<=fdparam_1.N+1;i++){
for (j=0;j<=fdparam_1.N+1;j++){
sum1+=r0[(i)+((fdparam_1.N+2)*j)];
}
}
double n_act = sum1*vol;
printf("Time = %lf \t Initial Nr. of Molecules is: %e \n",t,n_act);
int l = 0;
add_source(fdparam_1.N,r,r0,fdparam_1.Dt);
t=0;
int k=0;
while(t<=fdparam_1.t_domain){
swap(r0,r);
density_solve(fdparam_1.N,r,r0,ux0,vy0,fdparam_1.Dt,fdparam_1.diff,fdparam_1.MAXIT); //uses ux and vy calculated from Navier Stokes in the velocity solver to calculate density
// creating multiple files to store the density values during the simulation at every Del_t time interval
if(((int)(t*100))%fdparam_1.t_domain==0){
char filename[sz+1];
sprintf(filename,"density%d.txt",l);
fp1[l]=fopen(filename,"w");
for (i=0;i<=fdparam_1.N+1;i++){
for (j=0;j<=fdparam_1.N+1;j++){
map[i][j]=r[(i)+(fdparam_1.N+2)*j];
fprintf(fp1[l],"%lf \t",map[i][j]);
}
fprintf(fp1[l],"\n");
}
fclose(fp1[l]);
sum=r[0];
for (i=0;i<=fdparam_1.N+1;i++){
for (j=0;j<=fdparam_1.N+1;j++){
sum+=r[(i)+((fdparam_1.N+2)*j)];
}
}
n_calc=sum*vol;
printf("Time = %lf \t Calculated Nr. of Molecules = %e \n",t,n_act);
}
l++;
t+=fdparam_1.Dt;
}
void add_source(int n, double *x, double *s, double dt)
{
int i, size;
size = (n+2)*(n+2);
for (i=0; i<size; i++)
{
x[i]+=s[i]; //add source terms to the density
}
}
I am sorry the code is divided into numerous functions and header files and it is really difficult for me to prepare a minimal working code out of it. The above is my complete main function but here is what is happening now when I run the gdb debugger again without supplying any breakpoint, it seems to be executing the step where it is supposed to print t and n_act because this is the actual expected output which I am supposed to get but I get segmentation fault instead,
Printing source densities now:
Time = 0.000000 Initial Nr. of Molecules is: 8.820000e+06
Time = 0.000000 Calculated Nr. of Molecules = 8.820000e+06
Time = 10.000000 Calculated Nr. of Molecules = 8.820000e+06
Time = 20.000000 Calculated Nr. of Molecules = 8.820000e+06
... and so on till Time=1000
Where the issue is:
Based on your previous post, Segmentation fault - Two functions don't run simultaneously, where N is the number of points, it looks like your indexes are going of of bounds.
How to resolve it:
Revise your loop comparisons for i and for j where used for map.
I have used a omp_get_wtime() but when i want to print the time i always get 0.00, where is the problem ?
#define SIZE 500
#define nthreads 10
(...)
void sumTab(int mX[][SIZE], int mY[][SIZE], int mZ[][SIZE]) {
int i,k;
double start = omp_get_wtime();
#pragma omp parallel for schedule(dynamic,3) private(i) num_threads(nthreads)
for(i=0 ; i<SIZE ; i++)
{
for(k=0 ; k<SIZE ; k++)
{
mZ[i][k]=mX[i][k]+mY[i][k];
printf("Thread no %d \t [%d] [%d] result: %d\n", omp_get_thread_num(),i,k, mZ[i][k]);
}
}
printf("Time: \t %f \n", omp_get_wtime()-start);
}
Make sure you include the omp.h library in the header of the file.
#include <omp.h>
double start_time = omp_get_wtime();
#pragma omp parallel [...]
// code
double time = omp_get_wtime() - start_time;
This library will remove this warning in compilation:
warning: implicit declaration of function ‘omp_get_wtime’ [-Wimplicit-function-declaration]
And the time will show correctly.
Try to print with "% g" that leaves it as scientific notation.
Declare the time where the program ends, after which you take the difference between the start time and the end time, output the difference. that should solve it as i did something similar some months ago
THis is what your code should look like:
double dif;
double start = omp_get_wtime( ); //start the timer
//beginning of computation
..
...
//end of computation
double end = omp_get_wtime();// end the timer
dif = end - start // stores the difference in dif
printf("the time of dif is %f", dif);
//this should point you in the way
This is because of precision loss in converting the double to float.
Try to print time with format specifier "%ld" for double insted of "%f".
printf("the time of dif is %lf", dif);
The program execution takes time in milliseconds or maybe less than that.
Declare the time where the program ends, after which you take the difference between the start time and the end time, output the difference. that should solve it as i did something similar some months ago
Your routine could be too fast for the resolution of omp_get_wtime. If you only want to measure the time and don't care about the final contents of mZ, you can repeat the test a number of times and divide the final number by the number of repetitions:
#define REPS 1024
...
...
double acumtime = 0.0;
for (rep = 0; rep < REPS; rep++)
{
double start = omp_get_wtime();
#pragma omp parallel for schedule(dynamic,3) private(i) num_threads(nthreads)
for(i=0 ; i<SIZE ; i++)
{
for(k=0 ; k<SIZE ; k++)
{
mZ[i][k]=mX[i][k]+mY[i][k];
printf("Thread no %d \t [%d] [%d] result: %d\n", omp_get_thread_num(),i,k, mZ[i][k]);
}
}
acumtime += omp_get_wtime()-start;
}
printf ("Elapsed time is: %f\n", acumtime/REPS);
You may also want to supress printf's inside the parallel block, as this might be a severe cause of slowdown.
I had this same problem and while setprecision did the trick in c++,
you can use the following code in c. In order to see the difference you have to print the results with high precision.
double exec_time;
double start = omp_get_wtime();
//beginning of computation
...
//end of computation
double end = omp_get_wtime();
exec_time = end - start;
printf("the time difference is %15.15f", exec_time);
#mcleod_ideafix was right when he wrote about the suppression of printf.
You should definitely remove the call to printf function from within the loop as it may skew the result greatly. Bear in mind that call to printf will at some stage involve transition to kernel mode and this itself is costly operation in terms of CPU cycles.
I apologize in advance for my lack of knowledge regarding stack smashing in C.
I'm on ubuntu 12.04 editing with Code::Blocks.
I have written a simple C program that causes stack smashing, but internet searches have turned up little useful advice as to why this is happening.
Example C code:
#include<stdio.h>
struct point3
{float x, y, z;};
struct quadPolygon
{struct point3 vert1, vert2, vert3, vert4;};
int writeLine(const char * objString)
{FILE *file; file = fopen("aPlane.obj","a+"); fprintf(file,"%s",objString); fclose(file); return 0;};
int writeOBJ(struct quadPolygon myPoly)
{
char objString[] = "# plane def\n"; writeLine(objString);
snprintf(objString, 128, "v %f %f %f \n", myPoly.vert1.x, myPoly.vert1.y, myPoly.vert1.z); writeLine(objString);
snprintf(objString, 128, "v %f %f %f \n", myPoly.vert2.x, myPoly.vert2.y, myPoly.vert2.z); writeLine(objString);
snprintf(objString, 128, "v %f %f %f \n", myPoly.vert3.x, myPoly.vert3.y, myPoly.vert3.z); writeLine(objString);
snprintf(objString, 128, "v %f %f %f \n", myPoly.vert4.x, myPoly.vert4.y, myPoly.vert4.z); writeLine(objString);
char objStringSmooth[] = "s off\n"; writeLine(objStringSmooth);
char objStringFace[] = "f 1 2 3 4\n"; writeLine(objStringFace);
return 0;
};
int main()
{
struct quadPolygon myPoly1 =
{
.vert1.x=1.0, .vert1.y=-1.0, .vert1.z=0.0,
.vert2.x=1.0, .vert2.y=1.0, .vert2.z=0.0,
.vert3.x=-1.0, .vert3.y=1.0, .vert3.z=0.0,
.vert4.x=-1.0, .vert4.y=-1.0, .vert4.z=0.0
};
writeOBJ(myPoly1);
return 0;
};
Why is the stack smashing and how could I change my code to avoid this? Is this related to using pointers incorrectly in the code above? I'm a little new to C as you can probably tell, but have some programming experience with other languages.
I have read that "Stack Smashing is actually a protection mechanism used by gcc to detect buffer overflow attacks" and "It means that you wrote to some variables on the stack in an illegal way, most likely as the result of a Buffer overflow".
Thank you for any responses/answers.
Update -
Based on Evan's comment, here is revised code that works. Perhaps this may help someone else.
#include<stdio.h>
struct point3
{float x, y, z;};
struct quadPolygon
{struct point3 vert1, vert2, vert3, vert4;};
int writeOBJ(struct quadPolygon myPoly)
{
FILE *file; file = fopen("aPlane.obj","a+");
fprintf(file,"%s","# plane def\n");
char objString[128];
snprintf(objString, sizeof(objString), "v %f %f %f \n", myPoly.vert1.x, myPoly.vert1.y, myPoly.vert1.z);
fprintf(file,"%s",objString);
snprintf(objString, sizeof(objString), "v %f %f %f \n", myPoly.vert2.x, myPoly.vert2.y, myPoly.vert2.z);
fprintf(file,"%s",objString);
snprintf(objString, sizeof(objString), "v %f %f %f \n", myPoly.vert3.x, myPoly.vert3.y, myPoly.vert3.z);
fprintf(file,"%s",objString);
snprintf(objString, sizeof(objString), "v %f %f %f \n", myPoly.vert4.x, myPoly.vert4.y, myPoly.vert4.z);
fprintf(file,"%s",objString);
char objStringSmooth[] = "s off\n";
fprintf(file,"%s",objStringSmooth);
char objStringFace[] = "f 1 2 3 4\n";
fprintf(file,"%s",objStringFace);
fclose(file);
return 0;
};
int main()
{
struct quadPolygon myPoly1 =
{
.vert1.x=1.0, .vert1.y=-1.0, .vert1.z=0.0,
.vert2.x=1.0, .vert2.y=1.0, .vert2.z=0.0,
.vert3.x=-1.0, .vert3.y=1.0, .vert3.z=0.0,
.vert4.x=-1.0, .vert4.y=-1.0, .vert4.z=0.0
};
writeOBJ(myPoly1);
return 0;
};
Thanks again everyone.
This is where your problem is:
char objString[] = "# plane def\n"; writeLine(objString);
snprintf(objString, 128, "v %f %f %f \n", myPoly.vert1.x, myPoly.vert1.y, myPoly.vert1.z); writeLine(objString);
snprintf(objString, 128, "v %f %f %f \n", myPoly.vert2.x, myPoly.vert2.y, myPoly.vert2.z); writeLine(objString);
snprintf(objString, 128, "v %f %f %f \n", myPoly.vert3.x, myPoly.vert3.y, myPoly.vert3.z); writeLine(objString);
snprintf(objString, 128, "v %f %f %f \n", myPoly.vert4.x, myPoly.vert4.y, myPoly.vert4.z); writeLine(objString);
objString is an array with strlen("# plane def\n") + 1 characters of space. Then you use snprintf on that buffer passing 128 (which is WAY too large).
I would re-write it this way:
writeLine("# plane def\n");
char objString[128]
snprintf(objString, sizeof(objString), "v %f %f %f \n", myPoly.vert1.x, myPoly.vert1.y, myPoly.vert1.z); writeLine(objString);
snprintf(objString, sizeof(objString), "v %f %f %f \n", myPoly.vert2.x, myPoly.vert2.y, myPoly.vert2.z); writeLine(objString);
snprintf(objString, sizeof(objString), "v %f %f %f \n", myPoly.vert3.x, myPoly.vert3.y, myPoly.vert3.z); writeLine(objString);
snprintf(objString, sizeof(objString), "v %f %f %f \n", myPoly.vert4.x, myPoly.vert4.y, myPoly.vert4.z); writeLine(objString);
SIDE POINT:
Why are you opening and closing the file for every line written? That is incredibly inefficient...
Would be better to open the file once at program start, write all your lines, then close it when finished. This will also make the code simpler.
you can confirm that you are getting a valid FILE* by fopen..
by explicit check of NULL pointer.
The problem is with the following line:
char objString[] = "# plane def\n";
This only allocates just enough space for the string "# plane def\n", and later on, you write longer strings into it (using snprintf).
Since you're already using the constant value 128, how about:
char objString[128];
strcpy(objString, "# plane def\n");
writeLine(objString);
/* continue as before */
Note that strcpy can smash the stack too, so make sure the destination has enough space for whatever you're copying in.
As it is already answered by Evan Teran. But I would like to suggest few ways to detect such problems :
Try compiling using gcc -fno-stack-protector stack.c and check whether it still gives you stack smash detected.
use -g flag for gnu-debugger. As gcc -g stack.c and then gdb a.out -> run. It will stop execution where it got problem. Then you can type where in gdb to see which line of code is root of the problem.