Segmentation fault while assigning array value - c

void particle_initialize()
{
int i;
for (i = 0; i<particlenumber; i++)
{
Pu[i]=0;
}
return; }
void forceon_particle()
{
for (i = 0; i<particlenumber; i++)
{
FDx[i]=(U[i]-Pu[i])/taup;
FDy[i]=(V[i]-Pv[i])/taup;
}
return; }
void particle_motion()
{
int i;
for (i = 0; i<particlenumber; i++)
{
Pu[i]=Pu[i]+FDx[i]*tp;
Px[i]=Px[i]+Pu[i]*tp;}
return;
}
Hi Everyone, I'm unable to understand why I'm getting segmentation error in the function particle_motion.
The error comes only when I try assigning Px[i]=Px[i]+Pu[i]*tp; Py[i]=Py[i]+Pv[i]*tp;. Kindly help.
/*Developing flow in a Two Dimensional channel*/
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#define NX 101
#define NY 101
#define Q 9
#define T 300001
#define u_in 0.01
#define omega 1
#define kvisc 1/6
#define W0 4.0/9.0
#define W1 1.0/9.0
#define W2 1.0/36.0
#define rho0 1.0
#define particlenumber 10000
#define dp 0.01
#define rhop 2
#define tp 1/omega
#define pi 3.14
int cx [Q]={0,1,0,-1,0,1,-1,-1,1};
int cy [Q]={0,0,1,0,-1,1,1,-1,-1};
double t [Q]={W0,W1,W1,W1,W1,W2,W2,W2,W2};
int next_x [NX][Q];
int next_y [NY][Q];
double f1 [NX][NY][Q];
double f2 [NX][NY][Q];
double ux [NX][NY];
double uy [NX][NY];
double uxeq [NX][NY];//eq velocity for effect of particle
double uyeq [NX][NY];
double ustar [NX][NY];//forcing term added to ueq
double vstar [NX][NY];
double rho [NX][NY];
double Px [particlenumber];//location of particles
double Py [particlenumber];
double Pu [particlenumber];//velocity of particles
double Pv [particlenumber];
double FDx [particlenumber];// drag force
double FDy [particlenumber];
double U [particlenumber];//velocity of particle
double V [particlenumber];
double FPx [particlenumber];//force on fluid due to particle
double FPy [particlenumber];
double uforcing [particlenumber];
double rhoatpar [particlenumber];
double vforcing [particlenumber];
void tables();
void initialise();
void cal_obs();
void streaming();
void collision();
void density_data();
void particle_initialize();
void forceon_particle();
void intrapolation_velocity();
void particle_motion();
void forceon_fluid();
void intrapolation_density();
void reverse_intrapolation();
int main()
{
int count=0, k;
tables();
initialise();
particle_initialize();
for(k=0;k<T;k++)
{
//printf("k=%d\t",k);
cal_obs();
collision();
streaming();
if (k % 10000 ==0)
{
density_data(count, k);
}
intrapolation_velocity();
forceon_particle();
intrapolation_density();
forceon_fluid();
reverse_intrapolation();
particle_motion();
}
return 0;
}
void tables()
{
int x,y,i;
for(x=0; x<NX; x++)
{
for (y=0; y<NY; y++)
{
for (i=0; i<Q; i++)
{
next_x[x][i] = x + cx[i];
if (next_x[x][i]>NX-1)
next_x[x][i] = 0;
if (next_x[x][i]<0)
next_x[x][i] = NX-1;
next_y[y][i] = y + cy[i];
if (next_y[y][i]>NY-1)
next_y[y][i] = 0;
if (next_y[y][i]<0)
next_y[y][i] = NY-1;
}
}
}
return;
}
void initialise()
{
int x,y,i;
for(x=0; x<NX; x++)
{
for (y=0; y<NY; y++)
{
ustar[x][y]=0;//initialize forcing term zero
vstar[x][y]=0;
for (i=0; i<Q; i++)
{
f1[x][y][i]=rho0*t[i];
}
}
}
return;
}
void cal_obs()
{
int x,y,i;
double dense;
for(x=0; x<NX; x++)
{
for (y=0; y<NY; y++)
{
dense=ux[x][y]=uy[x][y]=0.0;
for (i=0; i<Q; i++)
{
dense += f1[x][y][i];
ux[x][y] += f1[x][y][i]*cx[i];
uy[x][y] += f1[x][y][i]*cy[i];
}
if(dense != 0.0)
{
rho[x][y] = dense;
ux[x][y] = ux[x][y]/rho[x][y];
uy[x][y] = uy[x][y]/rho[x][y];
}
else
{
rho[x][y] = 0.0;
ux[x][y] = 0.0;
uy[x][y] = 0.0;
}
}
}
for(x=0; x<NX; x++)
{
ux[x][0]=u_in;
ux[x][NY-1]=-u_in;
}
return;
}
void collision()
{
int x,y,i;
double udotc,u2,feq;
for(x=0; x<NX; x++)
{
for (y=0; y<NY; y++)
{
for (i=0; i<Q; i++)
{
uxeq[x][y]=ustar[x][y]+ux[x][y];
uyeq[x][y]=vstar[x][y]+uy[x][y];
udotc = uxeq[x][y]*cx[i]+uyeq[x][y]*cy[i];
u2=uxeq[x][y]*uxeq[x][y] + uyeq[x][y]*uyeq[x][y];
feq = t[i]*rho[x][y]*(1+3*udotc+4.5*udotc*udotc-1.5*u2);
f1[x][y][i]=f1[x][y][i]*(1-omega)+feq*omega;
}
}
}
return;
}
void streaming()
{
int x,y,i,newx,newy;
double rho_w;
for(x=0; x<NX; x++)
{
for (y=0; y<NY; y++)
{
for (i=0; i<Q; i++)
{
newx=next_x [x][i];
newy=next_y[y][i];
f2[newx][newy][i] = f1[x][y][i];
}
}
}
for(x=0; x<NX; x++)
{
for (y=0; y<NY; y++)
{
for (i=0; i<Q; i++)
{
f1[x][y][i]=f2[x][y][i];
}
}
}
return;
}
void density_data(int data_counter, int id)
{
int x, y;
FILE *f3;
char phase [100];
/* Data for Tecplot*/
sprintf ( phase,"phaseVelocity2D_%d.csv",id);
f3 = fopen(phase, "w");
fprintf(f3," X,Y,Rho,U,V\n");
for (y =0; y < NY; y++)
{ for (x = 0; x < NX; x++)
fprintf(f3,"%d%c%d%c%lf%c%lf%c%lf\n",x,',',y,',',rho[x][y],',',ux[x][y],',',uy[x][y]);
}
fflush(f3);
fclose(f3);
int i;
FILE *f4;
char particle [100];
sprintf ( particle,"particle_%d.csv",id);
f4 = fopen(particle, "w");
fprintf(f4," Id,X,Y\n");
for (i =0; i < particlenumber; i++)
{
fprintf(f4,"%d%c%lf%c%lf\n",i,',',Px[i],',',Py[i]);
}
fflush(f4);
fclose(f4);
return;
}
void particle_initialize()
{
int i;
srand(time(0));
float randomx;
for (i = 0; i<particlenumber; i++)
{
randomx=(float)rand()/RAND_MAX;
Px[i]=randomx*NX;
Pu[i]=0;
}
float randomy;
for (i = 0; i<particlenumber; i++)
{
randomy=(float)rand()/RAND_MAX;
Py[i]=randomy*NY;
Pv[i]=0;
}
return;
}
void forceon_particle()
{
int i;
double taup;
taup=(rhop*dp*dp)/(18*kvisc*rho0);
for (i = 0; i<particlenumber; i++)
{
FDx[i]=(U[i]-Pu[i])/taup;
FDy[i]=(V[i]-Pv[i])/taup;
}
return;
}
void intrapolation_velocity()
{
int i;
int node1x, node1y, node2x, node2y,node3x, node3y,node4x, node4y;
double w1,w2,w3,w4;
for (i = 0; i<particlenumber; i++)
{
node1x=trunc(Px[i]);
node1y=trunc(Py[i]);
node2x=node1x;
node2y=node1y+1;
node3x=node1x+1;
node3y=node1y+1;
node4x=node1x+1;
node4y=node1y;
w1=(Px[i]-node1x)*(Px[i]-node1x)+(Py[i]-node1y)*(Py[i]-node1y);
w1=sqrt(w1);
w2=(Px[i]-node2x)*(Px[i]-node2x)+(Py[i]-node2y)*(Py[i]-node2y);
w2=sqrt(w2);
w3=(Px[i]-node3x)*(Px[i]-node3x)+(Py[i]-node3y)*(Py[i]-node3y);
w3=sqrt(w3);
w4=(Px[i]-node4x)*(Px[i]-node4x)+(Py[i]-node4y)*(Py[i]-node4y);
w4=sqrt(w4);
U[i]=w1*ux[node1x][node1y]+w2*ux[node2x][node2y]+w3*ux[node3x][node3y]+w4*ux[node4x][node4y];
U[i]=U[i]/(w1+w2+w3+w4);
V[i]=w1*uy[node1x][node1y]+w2*uy[node2x][node2y]+w3*uy[node3x][node3y]+w4*uy[node4x][node4y];
V[i]=V[i]/(w1+w2+w3+w4);
}
return;
}
void particle_motion()
{
int i;
double A,B;
for (i = 0; i<particlenumber; i++)
{
Pu[i]=Pu[i]+FDx[i]*tp;//Pu[i] added so that it adds previous velocity
Pv[i]=Pv[i]+FDy[i]*tp;
}
for (i = 0; i<particlenumber; i++)
{
Px[i]=Px[i]+Pu[i]*tp;
Py[i]=Py[i]+Pv[i]*tp;
//if particle goes out of bound we r introducing periodic BC
if(Px[i]<0||Px[i]>(NX-1))
{
if(Px[i]<0)
{Px[i]=Px[i]+NX-1;}
else if(Px[i]>(NX-1))
{Px[i]=Px[i]-NX+1;}
}
if(Py[i]<0||Py[i]>(NY-1))
{
if(Py[i]<0)
{Py[i]=Py[i]+NY-1;}
else if(Py[i]>(NY-1))
{Py[i]=Py[i]-NY+1;}
}
}
return;
}
void forceon_fluid()
{
int i;
double taup;
long double mp;
mp=(1/6)*(pi)*rhop*dp*dp*dp;
taup=(rhop*dp*dp)/(18*kvisc*rho0);
for (i = 0; i<particlenumber; i++)
{
FPx[i]=mp*(U[i]-Pu[i]);
FPx[i]=FPx[i]/taup;
FPy[i]=mp*(V[i]-Pv[i]);
FPy[i]=FPy[i]/taup;
uforcing[i]=(FPx[i])/(rhoatpar[i]*omega);
vforcing[i]=(FPy[i])/(rhoatpar[i]*omega);
}
return;
}
void intrapolation_density()
{
int i;
int node1x, node1y, node2x, node2y,node3x, node3y,node4x, node4y;
double w1,w2,w3,w4;
for (i = 0; i<particlenumber; i++)
{
node1x=trunc(Px[i]);
node1y=trunc(Py[i]);
node2x=node1x;
node2y=node1y+1;
node3x=node1x+1;
node3y=node1y+1;
node4x=node1x+1;
node4y=node1y;
w1=(Px[i]-node1x)*(Px[i]-node1x)+(Py[i]-node1y)*(Py[i]-node1y);
w1=sqrt(w1);
w2=(Px[i]-node2x)*(Px[i]-node2x)+(Py[i]-node2y)*(Py[i]-node2y);
w2=sqrt(w2);
w3=(Px[i]-node3x)*(Px[i]-node3x)+(Py[i]-node3y)*(Py[i]-node3y);
w3=sqrt(w3);
w4=(Px[i]-node4x)*(Px[i]-node4x)+(Py[i]-node4y)*(Py[i]-node4y);
w4=sqrt(w4);
rhoatpar[i]=w1*rho[node1x][node1y]+w2*rho[node2x][node2y]+w3*rho[node3x][node3y]+w4*rho[node4x][node4y];
rhoatpar[i]=rhoatpar[i]/(w1+w2+w3+w4);
}
return;
}
void reverse_intrapolation()
{
int i;
int node1x, node1y, node2x, node2y,node3x, node3y,node4x, node4y;
double w1,w2,w3,w4;
int x,y;
for(x=0; x<NX; x++)
{
for (y=0; y<NY; y++)
{
ustar[x][y]=0;//initialize forcing term zero
vstar[x][y]=0;
}
}
for (i = 0; i<particlenumber; i++)
{
node1x=trunc(Px[i]);
node1y=trunc(Py[i]);
node2x=node1x;
node2y=node1y+1;
node3x=node1x+1;
node3y=node1y+1;
node4x=node1x+1;
node4y=node1y;
w1=(Px[i]-node1x)*(Px[i]-node1x)+(Py[i]-node1y)*(Py[i]-node1y);
w1=sqrt(w1);
w2=(Px[i]-node2x)*(Px[i]-node2x)+(Py[i]-node2y)*(Py[i]-node2y);
w2=sqrt(w2);
w3=(Px[i]-node3x)*(Px[i]-node3x)+(Py[i]-node3y)*(Py[i]-node3y);
w3=sqrt(w3);
w4=(Px[i]-node4x)*(Px[i]-node4x)+(Py[i]-node4y)*(Py[i]-node4y);
w4=sqrt(w4);
ustar[node1x][node1y]=ustar[node1x][node1y]+(w1*uforcing[i])/(w1+w2+w3+w4);
vstar[node1x][node1y]=vstar[node1x][node1y]+(w1*vforcing[i])/(w1+w2+w3+w4);
ustar[node2x][node2y]=ustar[node2x][node2y]+(w1*uforcing[i])/(w1+w2+w3+w4);
vstar[node2x][node2y]=vstar[node2x][node2y]+(w1*vforcing[i])/(w1+w2+w3+w4);
ustar[node3x][node3y]=ustar[node3x][node3y]+(w1*uforcing[i])/(w1+w2+w3+w4);
vstar[node3x][node3y]=vstar[node3x][node3y]+(w1*vforcing[i])/(w1+w2+w3+w4);
ustar[node4x][node4y]=ustar[node4x][node4y]+(w1*uforcing[i])/(w1+w2+w3+w4);
vstar[node4x][node4y]=vstar[node4x][node4y]+(w1*vforcing[i])/(w1+w2+w3+w4);
}
return;
}
I have added the whole code as the error may be due to other functions which might also access the arrays.

The issue is at this statement.
V[i] = w1* uy[node1x][node1y] + w2* uy[node2x][node2y] + w3 * uy[node3x][node3y] + w4*uy[node4x][node4y];
Here,the arrays are uy[101][101], ux[101][101]. Look at the values of node1x and node1y:
node1x=trunc(Px[i]);
node1y=trunc(Py[i]);
See the values of Px[i] and Py[i] :
Px[i]=randomx*NX; // NX=101. randomx ranges from 0 to 1. randomx=(float)rand()/RAND_MAX
Py[i]=randomy*NY; // NY=101. randomy ranges from 0 to 1. randomy=(float)rand()/RAND_MAX
I think at some point of time randomx = 1, then Px[i] = 101, then node1x = 101 then you are accessing uy[101][node1y]. This causes segmentation fault because the array is uy[101][101] , and you cannot access uy[101][node1y]element.

Related

In C, I'm having trouble getting an Index sorted High to Low and vice versa

I'm working on a project involving a preset array:
primaryArray[8] = {8, 4, 2, 16, 32, 124, 64, 256};
Im calling a function before the main, its not quite working. Here is the code.
void lowhighSort(int primaryArray[], int arrayLength) {
int i;
int a;
int indexMin;
for (i = 0; i < arrayLength - 1; ++i){
indexMin = i;
for (a = (i + 1) + 1; a < arrayLength; ++a) {
if (primaryArray[a] < primaryArray[indexMin]){
indexMin = a;
}
simpleSwap(&primaryArray[indexMin], &primaryArray[i]);
}
}
}
void highlowSort(int primaryArray[], int arrayLength) {
int i;
int a;
int indexMin;
for (i = 0; i < arrayLength - 1; ++i){
indexMin = i;
for (a = i + 1; a < arrayLength; ++a) {
if(primaryArray[a] > primaryArray[indexMin])
indexMin = a;
simpleSwap(&primaryArray[indexMin], &primaryArray[i]);
}
}
}
My "simpleSwap" might be the mistake, when learning I didn't quite understand entirely what the * did. Regardless, here it is as well:
void simpleSwap(int* x, int* y) {
int temp = *x;
*x = *y;
*y = temp;
}
*edit
This is part of a "larger" code so I'm not entirely sure if perhaps the error is elsewhere.
#include <stdio.h>
#include <stdlib.h>
void simpleSwap(double* x, double* y) {
double temp = *x;
*x = *y;
*y = temp;
}
double largest(double Array[], double Length) {
double largestNum = Array[0];
for (int i = 1; i < Length; ++i) {
if(largestNum < Array[i]) {
largestNum = Array[i];
}
}
return largestNum;
}
double smallest(double Array[], double Length) {
double smallestNum = Array[0];
for (int i = 1; i < Length; ++i) {
if(smallestNum > Array[i]) {
smallestNum = Array[i];
}
}
return smallestNum;
}
void lowhighSort(double Array[], double Length) {
int a;
int indexMin;
for (int i = 0; i < Length; ++i){
indexMin = i;
for (a = (i + 1); a < Length; ++a) {
if (Array[a] < Array[indexMin]){
indexMin = a;
simpleSwap(&Array[indexMin], &Array[i]);
}
}
}
}
void highlowSort(double Array[], double Length) {
int a;
int indexMin;
for (int i = 0; i < Length; ++i){
indexMin = i;
for (a = (i + 1); a < Length; ++a) {
if(Array[a] > Array[indexMin]){
indexMin = a;
simpleSwap(&Array[indexMin], &Array[i]);
}
}
}
}
float arrayAverage (double Array[], double Length) {
int i;
double arrayAverage = 0;
for (i = 0; i < Array[i]; ++i) {
arrayAverage = Array[i] + arrayAverage;
}
return arrayAverage;
}
int main()
{
double primaryArray[8] = {8, 4, 2, 16, 32, 124, 64, 256};
double arrayLength = sizeof(primaryArray)/sizeof(primaryArray[0]);
double ancillaryArray[10] = {8, 4, 2, 16, 32, 124, 64, 256};
printf("Primary Array:\n");
printf("\nLargest Array Element: %.1lf\n", largest(primaryArray, arrayLength));
printf("Smallest Array Element: %.1lf\n\n", smallest(primaryArray, arrayLength));
lowhighSort(primaryArray, arrayLength);
printf("Array Ascending Order: ");
for(int i = 0; i < 8; ++i){
printf("%.1lf, ", primaryArray[i]);
}
printf("\n");
highlowSort(primaryArray, arrayLength);
printf("Array Descending Order: ");
for(int i = 0; i < 8; ++i){
printf("%.1lf, ", primaryArray[i]);
}
printf("\n");
printf("\nArray Element Average: %.3lf", (arrayAverage(primaryArray, arrayLength))/8);
int ancillaryarrayLength = sizeof(ancillaryArray)/sizeof(ancillaryArray[0]);
printf("\n\nPlease Finish Ancillary Array (Max 10 Elements)\nCurrent Elements: ");
for(int i = 0; i < arrayLength; ++i) {
printf("%.1lf, ", ancillaryArray[i]);
}
printf("\nEnter Elements: ");
for (int i = 8; i < 10; ++i) {
scanf("%lf", &ancillaryArray[i]);
}
printf("\nLargest Array Element: %.1lf\n", largest(ancillaryArray, ancillaryarrayLength));
printf("Smallest Array Element: %.03lf\n", smallest(ancillaryArray, ancillaryarrayLength));
lowhighSort(ancillaryArray, ancillaryarrayLength);
printf("Array Ascending Order: ");
for(int i = 0; i < 10; ++i){
printf("%.3lf, ", ancillaryArray[i]);
}
printf("\n");
highlowSort(ancillaryArray, ancillaryarrayLength);
printf("Array Descending Order: ");
for(int i = 0; i < 10; ++i){
printf("%.3lf, ", ancillaryArray[i]);
}
printf("\n");
printf("Array Element Average: %.4lf", (arrayAverage(ancillaryArray, ancillaryarrayLength))/10);
return 0;
}
Here is the final code, it works as intended! Thank you all for your help.

fprintf in a while loop will only print my data 10 times to a file

ran into a problem regarding fprintf, we want to write a double array into our file for every loop in our main's while loop, however when this loop goes higher than 10 it simply stops fprintf'ing.
The function in question is "store_trash_file". Also the program is controlled by a few defines at top.
Day_max = controls the amount of loops in our while loop
SIZE = with higher SIZE it seems it will fprintf less, and with a smaller it will fprintf more lines.
Ill be putting up the entire code, so u can run it, perhaps keep an eye on the create directories function, as it will make folders and some txts
Any help is much appreciated
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <conio.h>
#include <io.h>
#include <process.h>
#define MARGIN 70
#define MARGIN2 30
#define NAREA 4
#define NSUBAREA 4
#define SIZE 20
#define DAY_MAX 20
#define AREAS_PER_TRUCK 4
#define LOWER1 6
#define LOWER2 8
#define LOWER3 10
#define UPPER1 8
#define UPPER2 10
#define UPPER3 12
typedef struct subarea
{
int co2_cost, time, emptied_subarea_counter, lower_random, upper_random, activity_level;
double average, total_trash_subarea_avg, sensorData[SIZE], sensorDataTotal[SIZE];
} subarea;
typedef struct area
{
subarea *subarea_array[NAREA + 1];
double average, total_trash_area_avg;
int emptied_area_counter;
} area;
void simulated_days(area *area_dynamic, area *area_static);
void average_trash(area *area);
void sensor_data_start(area *area, double start_var);
void compare_trash_to_empty(area *area_array[NAREA + 1], int *area_number_p);
void empty_trash(area *area, int *co2_counter_p, int *time_counter_p);
void store_trash_file(area *area_array[NAREA + 1]);
void create_areas(area *area_array[NAREA + 1]);
void empty_trash_static(area *area, int *co2_counter_static_p, int *time_counter_static_p);
void create_directories();
void make_txt_file(char file_name[30], char file_name2[30]);
int main(void)
{
int co2_counter = 0, time_counter = 0;
int co2_counter_static = 0, time_counter_static = 0;
int day_counter = 0;
int area_number;
int garbage_truck_amount = 0;
double *area_array_avg[DAY_MAX][NAREA];
double *subarea_array_avg[DAY_MAX][NAREA * NSUBAREA];
double *trashcan_array_avg[DAY_MAX][NAREA * NSUBAREA * SIZE];
area *area_array[NAREA + 1];
area *area_array_static[NAREA + 1];
srand(time(NULL));
for (int i = NAREA; i > 0; i -= AREAS_PER_TRUCK)
{
garbage_truck_amount++;
}
printf("Garbage trucks: %d\n", garbage_truck_amount);
create_areas(area_array);
create_areas(area_array_static);
create_directories();
int running = 1;
while (running)
{
for (int i = 1; i < NAREA + 1; i++)
{
simulated_days(area_array[i], area_array_static[i]);
average_trash(area_array[i]);
average_trash(area_array_static[i]);
}
for (int i = 1; i < NAREA + 1; i++)
{
for (int j = 0; j < NSUBAREA; j++)
{
printf("area array: %lf\n", area_array[i]->subarea_array[j]->average);
printf("area array static: %lf\n", area_array_static[i]->subarea_array[j]->average);
}
}
for (int i = 0; i < garbage_truck_amount; i++)
{
compare_trash_to_empty(area_array, &area_number);
empty_trash(area_array[area_number], &co2_counter, &time_counter);
for (int j = 1; j < NAREA + 1; j++)
{
average_trash(area_array[j]);
}
}
if (day_counter > 1 && day_counter % 14 == 0)
{
for (int i = 1; i < NAREA + 1; i++)
{
empty_trash_static(area_array_static[i], &co2_counter_static, &time_counter_static);
average_trash(area_array_static[i]);
}
}
store_trash_file(area_array);
printf("Day: %d\n", day_counter + 1);
for (int i = 0; i < NSUBAREA; i++)
{
for (int j = 1; j < NAREA + 1; j++)
{
printf("%lf\t", area_array[j]->subarea_array[i]->average);
printf("%lf\t", area_array_static[j]->subarea_array[i]->average);
}
printf("\n");
}
printf("\n");
day_counter++;
if(day_counter == DAY_MAX)
{
running = 0;
}
}
}
void simulated_days(area *area_dynamic, area *area_static)
{
for (int i = 0; i < NSUBAREA; i++)
{
for (int j = 0; j < SIZE; j++)
{
int x = ((rand() % (area_dynamic->subarea_array[i]->upper_random - area_dynamic->subarea_array[i]->lower_random + 1)) + area_dynamic->subarea_array[i]->lower_random);
area_dynamic->subarea_array[i]->sensorData[j] += x;
area_dynamic->subarea_array[i]->sensorDataTotal[j] += x;
area_static->subarea_array[i]->sensorData[j] += x;
area_static->subarea_array[i]->sensorDataTotal[j] += x;
}
}
}
void average_trash(area *area)
{
double sum[NSUBAREA];
double sum_total[NSUBAREA];
double area_trash_sum = 0;
double area_trash_sum_total = 0;
for (int i = 0; i < NSUBAREA; i++)
{
sum[i] = 0;
sum_total[i] = 0;
}
for (int i = 0; i < NSUBAREA; i++)
{
for (int j = 0; j < SIZE; j++)
{
sum[i] += area->subarea_array[i]->sensorData[j];
sum_total[i] += area->subarea_array[i]->sensorDataTotal[j];
}
area->subarea_array[i]->average = sum[i] / SIZE;
area->subarea_array[i]->total_trash_subarea_avg = sum_total[i] / SIZE;
}
for (int i = 0; i < NSUBAREA; i++)
{
area_trash_sum += area->subarea_array[i]->average;
area_trash_sum_total += area->subarea_array[i]->total_trash_subarea_avg;
}
area->average = area_trash_sum / NSUBAREA;
area->total_trash_area_avg = area_trash_sum_total / NSUBAREA;
}
void sensor_data_start(area *area, double start_var)
{
for (int i = 0; i < NSUBAREA; i++)
{
for (int j = 0; j < SIZE; j++)
{
area->subarea_array[i]->sensorData[j] = start_var;
area->subarea_array[i]->sensorDataTotal[j] = start_var;
}
}
}
void compare_trash_to_empty(area *area_array[NAREA + 1], int *area_number_p)
{
int highBlock = 0;
for (int i = 1; i < NAREA + 1; i++)
{
if (area_array[i]->average >= MARGIN)
{
if (area_array[i]->average > area_array[highBlock]->average)
{
highBlock = i;
}
}
}
*area_number_p = highBlock;
printf("\nhighblock %d\n", highBlock);
}
void empty_trash(area *area, int *co2_counter_p, int *time_counter_p)
{
for (int i = 0; i < NSUBAREA; i++)
{
if (area->subarea_array[i]->average > MARGIN2)
{
*co2_counter_p += area->subarea_array[i]->co2_cost;
*time_counter_p += area->subarea_array[i]->time;
area->subarea_array[i]->average = 0;
area->subarea_array[i]->emptied_subarea_counter++;
for (int j = 0; j < SIZE; j++)
{
if (area->subarea_array[i]->sensorData[j] <= 100)
{
area->subarea_array[i]->sensorData[j] = 0;
}
else if (area->subarea_array[i]->sensorData[j] > 100)
{
area->subarea_array[i]->sensorData[j] -= 100;
}
}
}
}
area->emptied_area_counter++;
}
void store_trash_file(area *area_array[NAREA + 1])
{
// int xcount = 0;
// int ycount = 0;
// double area_array_avg[NAREA];
// double subarea_array_avg[NAREA * NSUBAREA];
// double trashcan_array_avg[NAREA * NSUBAREA * SIZE];
FILE *output_filepointer;
char *dirname2 = "C:\\Users\\jacob\\Documents\\software\\projekter\\p1\\kode\\intelligenttrash\\data\\area";
char newdirname[150];
char newdirname2[150];
char newdirname3[150];
for (int i = 1; i < NAREA + 1; i++)
{
// area_array_avg[i - 1] = (area_array[i]->total_trash_area_avg);
snprintf(newdirname, 150, "%s%d\\area_average_total.txt", dirname2, i);
output_filepointer = fopen(newdirname, "a");
fprintf(output_filepointer, "%lf ", area_array[i]->total_trash_area_avg);
for (int j = 0; j < NSUBAREA; j++)
{
// subarea_array_avg[j + (ycount * NSUBAREA)] = (area_array[i]->subarea_array[j]->total_trash_subarea_avg);
snprintf(newdirname2, 150, "%s%d%s%d\\subarea_average_total.txt", dirname2, i, "\\subarea", j);
output_filepointer = fopen(newdirname2, "a");
fprintf(output_filepointer, "%lf ", area_array[i]->subarea_array[j]->total_trash_subarea_avg);
for (int z = 0; z < SIZE; z++)
{
// trashcan_array_avg[z + (xcount * SIZE)] = (area_array[i]->subarea_array[j]->sensorDataTotal[z]);
snprintf(newdirname3, 150, "%s%d%s%d\\trashcan_trash.txt", dirname2, i, "\\subarea", j);
output_filepointer = fopen(newdirname3, "a");
fprintf(output_filepointer, "%lf ", area_array[i]->subarea_array[j]->sensorDataTotal[z]);
}
// xcount++;
fprintf(output_filepointer, "\n");
output_filepointer = fopen(newdirname2, "a");
fprintf(output_filepointer, "\n");
}
// ycount++;
output_filepointer = fopen(newdirname, "a");
fprintf(output_filepointer, "\n");
}
fclose(output_filepointer);
}
void create_areas(area *area_array[NAREA + 1])
{
int percentage_added[3][2] = {{LOWER1, UPPER1}, {LOWER2, UPPER2}, {LOWER3, UPPER3}};
int activity_level;
for (int i = 0; i < NAREA + 1; i++)
{
area_array[i] = malloc(sizeof(area));
for (int j = 0; j < NSUBAREA; j++)
{
activity_level = (rand() % 3);
area_array[i]->subarea_array[j] = malloc(sizeof(subarea));
area_array[i]->subarea_array[j]->co2_cost = 50;
area_array[i]->subarea_array[j]->time = 50;
area_array[i]->subarea_array[j]->average = 0;
area_array[i]->subarea_array[j]->emptied_subarea_counter = 0;
area_array[i]->subarea_array[j]->total_trash_subarea_avg = 0;
area_array[i]->subarea_array[j]->lower_random = percentage_added[activity_level][0];
area_array[i]->subarea_array[j]->upper_random = percentage_added[activity_level][1];
area_array[i]->subarea_array[j]->activity_level = activity_level;
}
sensor_data_start(area_array[i], 0);
area_array[i]->average = 0;
area_array[i]->total_trash_area_avg = 0;
area_array[i]->emptied_area_counter = 0;
}
}
void empty_trash_static(area *area, int *co2_counter_static_p, int *time_counter_static_p)
{
for (int i = 0; i < NSUBAREA; i++)
{
*co2_counter_static_p += area->subarea_array[i]->co2_cost;
*time_counter_static_p += area->subarea_array[i]->time;
area->subarea_array[i]->average = 0;
area->subarea_array[i]->emptied_subarea_counter++;
for (int j = 0; j < SIZE; j++)
{
if (area->subarea_array[i]->sensorData[j] <= 100)
{
area->subarea_array[i]->sensorData[j] = 0;
}
else if (area->subarea_array[i]->sensorData[j] > 100)
{
area->subarea_array[i]->sensorData[j] -= 100;
}
}
}
area->emptied_area_counter++;
}
void create_directories()
{
int check;
char *dirname1 = "C:\\Users\\jacob\\Documents\\software\\projekter\\p1\\kode\\intelligenttrash\\data";
char *dirname2 = "C:\\Users\\jacob\\Documents\\software\\projekter\\p1\\kode\\intelligenttrash\\data\\area";
mkdir(dirname1);
for (int i = 1; i < NAREA + 1; i++)
{
char newdirname[100];
char newdirname2[100];
snprintf(newdirname, 100, "%s%d", dirname2, i);
mkdir(newdirname);
for (int j = 1; j < NSUBAREA + 1; j++)
{
snprintf(newdirname2, 100, "%s%d%s%d", dirname2, i, "\\subarea", j);
mkdir(newdirname2);
}
}
}
void make_txt_file(char file_name[30], char file_name2[30])
{
FILE *output_filepointer;
char *dirname2 = "C:\\Users\\jacob\\Documents\\software\\projekter\\p1\\kode\\intelligenttrash\\data\\area";
char newdirname[100];
char newdirname2[100];
for (int i = 1; i < NAREA + 1; i++)
{
if (file_name != "none")
{
snprintf(newdirname, 100, "%s%d\\%s.txt", dirname2, i, file_name);
output_filepointer = fopen(newdirname, "a");
}
for (int j = 1; j < NSUBAREA + 1; j++)
{
if (file_name2 != "none")
{
snprintf(newdirname2, 100, "%s%d%s%d\\%s.txt", dirname2, i, "\\subarea", j, file_name2);
output_filepointer = fopen(newdirname2, "a");
}
}
}
fclose(output_filepointer);
}

How to access an array in a different function

I am writing a program to solve Sudoku puzzles in C I declared the array in main() when I try and access it in a different function the compiler gives the error I've tried using pointers to the array but nothing seems to allow me to access it
error: ‘grid’ undeclared (first use in this function) 121 |
printf("%d ", &grid[i][i]);
How can I access this array from a different function?
Here is the code
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main()
{
int grid[9][9] =
{
{8,0,0,0,0,0,0,0,0},
{0,0,3,6,0,0,0,0,0},
{0,7,0,0,9,0,2,0,0},
{0,5,0,0,0,7,0,0,0},
{0,0,0,0,4,5,7,0,0},
{0,0,0,1,0,0,0,3,0},
{0,0,1,0,0,0,0,6,8},
{0,0,8,5,0,0,0,1,0},
{0,9,0,0,0,0,4,0,0}
};
int LineNum = 9;
int RowAmount = 9;
for (int i = 0; i < LineNum; ++i)
{
for (int i = 0; i < RowAmount; ++i)
{
printf("%d ", &grid[i][i]);
}
printf("\n");
}
}
int find_empty_box(int sudoku)
{
for (int x = 0; x <= 9; ++x)
{
for (int y = 0; y < 9; ++y)
{
if (sudoku[&x][&y] == 0)
{
return x, y;
}
}
return NULL, NULL;
}
}
int Answer_Valid(int sudoku, int guess, int row, int col)
{
int row_values = &sudoku[&row];
for (int i = 0; i < sudoku[&row]; ++i)
{
if (guess == sudoku[&row[&i]])
{
return false;
}
}
int column_values = &sudoku[&col];
for (int t = 0; t <= 9; ++t)
{
for (int n = 0; n < &sudoku[&col]; ++n)
{
if (&guess == &sudoku[&col[&n]])
{
return false;
}
}
}
int row_start = (row / 3) * 3;
int col_start = (col / 3) * 3;
for (int x = 0; x <= row_start && row_start + 3; ++x)
{
for (int y = 0; y < col_start && col_start + 3; ++y)
{
if (sudoku[&x][&y] == guess)
{
return false;
}
return true;
}
}
}
int Solver(sudoku, guess)
{
int row, col = find_empty_box(sudoku);
if (row == NULL)
{
return true;
}
for (int i = 0; i < 1||2||3||4||5||6||7||8||9; ++i)
{
if(Answer_Valid(sudoku, guess, row, col))
{
sudoku[&row][&col] = guess;
if(Solver(sudoku))
{
return true;
}
return false;
}
}
int LineNum = 9;
int RowAmount = 9;
for (int i = 0; i < LineNum; ++i)
{
for (int i = 0; i < RowAmount; ++i)
{
printf("%d ", &grid[i][i]);
}
printf("\n");
}
}

Can't swap top element with bottom element in matrix

I'm trying to write sliding puzzle where I'm using 3x3 matrix as board. In main function user inputs the number of tile which swaps positions with 0. Everything works except when I enter number that is located in a position above zero it does not swap positions with it. How do I correct that?
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#define empty_space 0
int m,n,i,j,z,y;
void print_matrix(int matrix[3][3])
{
for ( m=0; m<3; m++){
for (n=0; n<3; n++)
{
printf("%d\t",matrix[m][n]);
} printf("\n");
}
printf("\n");
}
void swap(int *i, int *j) {
int t = *i;
*i = *j;
*j = t;
}
void slide(int a[3][3] , int t)
{
for ( i=0; i<3; i++){
for ( j=0; j<3; j++)
{
if (a[i][j]==t)
{
if (a[i+1][j]==empty_space && i+1<=2)
{
swap(&a[i+1][j],&a[i][j]);break;
}
if (a[i-1][j]==empty_space && i-1>=0)
{
swap(&a[i][j],&a[i-1][j]);break;
}
if (a[i][j+1]==empty_space && j+1<=2)
{
swap(&a[i][j],&a[i][j+1]);break;
}
if (a[i][j-1]==empty_space && j-1>=0)
{
swap(&a[i][j],&a[i][j-1]);break;
}
}
}
}
}
int goal_test (int a[3][3],int b[3][3])
{
int flag=0;
for ( z=0; z<3; z++){
for ( y=0; y<3; y++){
if(a[z][y]==b[z][y])
flag++;
}
}
if (flag==9)
return 1;
else return 0;
}
int main()
{
static int mat[3][3]={{1,2,3},{6,0,4},{7,5,8}};
int goal[3][3]={{1,0,3},{6,5,4},{7,8,2}};
print_matrix(mat);
int x;
while(goal_test(mat,goal)==0)
{
printf("enter tile to slide:\t");
scanf("%d",&x);
slide(mat, x);
print_matrix(mat);
}
return 0;
}
Here's what happens:
Any number can swap its position as long as it's not located above zero

Pointers and Dynamic Memory

I have a function that returns a pointer to an array. I'm running it in a loop and free() seems to be giving me problems. I'm not sure where, but it appears that somewhere in the main loop the memory that I'm trying to free is being used. I'm using Xcode 3.2.1 in 10.6 | Debug | x86_64 build.
The program will run through the main loop one time; the second time it encounters the free() it gives me the following error:
malloc: *** error for object 0x100100180: incorrect checksum for freed object -
object was probably modified after being freed.
Can someone point out (no pun intended) what I'm doing wrong with pointers here?
Here is the program:
int main(int argc, char **argv) {
int *partition;
int lowerLimit;
int upperLimit;
// snip ... got lowerLimit and upperLimit from console arguments
// this is the 'main loop':
for (int i = lowerLimit; i <= upperLimit; i += 2) {
partition = goldbachPartition(i);
printOutput(partition[0], partition[1], i);
free(partition); // I get problems on the second iteration here
}
return 0;
}
int *goldbachPartition(int x) {
int solved = 0;
int y, z;
int *primes;
int *result;
result = intAlloc(2);
primes = atkinsPrimes(x);
for (int i = intCount(primes)-1; i >= 0; i--) {
y = primes[i];
for (int j = 0; j < y; j++) {
z = primes[j];
if (z + y >= x) {
break;
}
}
if (z + y == x) {
solved = 1;
result[0] = y;
result[1] = z;
break;
} else if (y == z) {
result[0] = 0;
result[1] = 0;
break;
}
}
free(primes);
return result;
}
int *atkinsPrimes(int limit) {
int *primes;
int *initialPrimes;
int *filtered;
int *results;
int counter = 0;
int sqrtLimit;
int xLimit;
int resultsSize;
primes = intAlloc(limit+1);
intFillArray(primes, limit+1, 0);
sqrtLimit = floor(sqrt(limit));
xLimit = floor(sqrt((limit+1) / 2));
// these loops are part of the Atkins Sieve implementation
for (int x = 1; x < xLimit; x++) {
int xx = x*x;
for (int y = 1; y < sqrtLimit; y++) {
int yy = y*y;
int n = 3*xx + yy;
if (n <= limit && n % 12 == 7) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
n += xx;
if (n <= limit && (n % 12 == 1 || n % 12 == 5)) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
if (x > y) {
n -= xx + 2*yy;
if (n <= limit && n % 12 == 11) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
}
}
}
for (int n = 5; n < limit; n++) {
if (primes[n] == 1) {
for (int k = n*n; k < limit; k += n*n) {
primes[k] = 0;
}
}
}
initialPrimes = intAlloc(2);
if (limit >= 2) {
initialPrimes[counter++] = 2;
}
if (limit >= 3) {
initialPrimes[counter++] = 3;
}
filtered = intFilterArrayKeys(primes, limit+1);
results = intMergeArrays(initialPrimes, filtered, counter, trueCount(primes, limit+1));
resultsSize = counter + trueCount(primes, limit+1);
free(primes);
free(initialPrimes);
free(filtered);
results[resultsSize] = 0;
return results;
}
int trueCount(int *subject, int arraySize) {
int count = 0;
for (int i = 0; i < arraySize; i++) {
if (subject[i] == 1) {
count++;
}
}
return count;
}
int intCount(int *subject) {
// warning: expects 0 terminated array.
int count = 0;
while (*subject++ != 0) {
count++;
}
return count;
}
void intFillArray(int *subject, int arraySize, int value) {
for (int i = 0; i < arraySize; i++) {
subject[i] = value;
}
}
int *intFilterArrayKeys(int *subject, int arraySize) {
int *filtered;
int count = 0;
filtered = intAlloc(trueCount(subject, arraySize));
for (int i = 0; i < arraySize; i++) {
if (subject[i] == 1) {
filtered[count++] = i;
}
}
return filtered;
}
int *intMergeArrays(int *subject1, int *subject2, int arraySize1, int arraySize2) {
int *merge;
int count = 0;
merge = intAlloc(arraySize1 + arraySize2);
for (int i = 0; i < arraySize1; i++) {
merge[count++] = subject1[i];
}
for (int i = 0; i < arraySize2; i++) {
merge[count++] = subject2[i];
}
return merge;
}
int *intAlloc(int amount) {
int *ptr;
ptr = (int *)malloc(amount * sizeof(int));
if (ptr == NULL) {
printf("Error: NULL pointer\n");
}
return ptr;
}
void printOutput(int num1, int num2, int rep) {
if (num1 == 0) {
printf("%d: No solution\n", rep);
exit(0);
} else {
printf("%d = %d + %d\n", rep, num1, num2);
}
}
Why is intAlloc not returning int* ?
int *intAlloc(int amount) {
int *ptr;
ptr = (int *)malloc(amount * sizeof(int));
if(ptr == NULL) {
printf("Error: NULL pointer\n");
exit(1);
}
return ptr; //like this
}
EDIT (after your update):
On atkinsPrimes() where is filtered being intAlloc()ed?
int *atkinsPrimes(int limit) {
int *primes;
int *initialPrimes;
int *filtered;
int *results;
int resultsSize;
primes = intAlloc(limit+1);
// ...
initialPrimes = intAlloc(2);
// ...
resultsSize = counter + trueCount(primes, limit+1);
free(primes);
free(initialPrimes);
free(filtered); // Where was it intAlloc()ed?
results[resultsSize] = 0; // make the array 0-terminated to make it easier to work with
return results;
}
EDIT (after your N-th update):
This is a compilable version of your code. It ran smooth on my machine, no crashes. Compiled with g++ (due to declarations of variables inside the for statement):
g++ (Debian 4.3.2-1.1) 4.3.2
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int *goldbachPartition(int x);
int *atkinsPrimes(int limit);
int trueCount(int *subject, int arraySize);
int intCount(int *subject) ;
void intFillArray(int *subject, int arraySize, int value);
int *intFilterArrayKeys(int *subject, int arraySize);
int *intAlloc(int amount);
void printOutput(int num1, int num2, int rep) ;
int *intMergeArrays(int *subject1, int *subject2, int arraySize1, int arraySize2);
int main(int argc, char **argv) {
if (argc < 3) {
printf("Usage: ./program <lower> <upper>\n");
return 0;
}
int *partition;
int lowerLimit = atoi(argv[1]);
int upperLimit = atoi(argv[2]);
// snip ... got lowerLimit and upperLimit from console arguments
// this is the 'main loop':
for (int i = lowerLimit; i <= upperLimit; i += 2) {
partition = goldbachPartition(i);
printOutput(partition[0], partition[1], i);
free(partition); // I get problems on the second iteration here
}
return 0;
}
int *goldbachPartition(int x) {
int solved = 0;
int y, z;
int *primes;
int *result;
result = intAlloc(2);
primes = atkinsPrimes(x);
for (int i = intCount(primes)-1; i >= 0; i--) {
y = primes[i];
for (int j = 0; j < y; j++) {
z = primes[j];
if (z + y >= x) {
break;
}
}
if (z + y == x) {
solved = 1;
result[0] = y;
result[1] = z;
break;
} else if (y == z) {
result[0] = 0;
result[1] = 0;
break;
}
}
free(primes);
return result;
}
int *atkinsPrimes(int limit) {
int *primes;
int *initialPrimes;
int *filtered;
int *results;
int counter = 0;
int sqrtLimit;
int xLimit;
int resultsSize;
primes = intAlloc(limit+1);
intFillArray(primes, limit+1, 0);
sqrtLimit = floor(sqrt(limit));
xLimit = floor(sqrt((limit+1) / 2));
for (int x = 1; x < xLimit; x++) {
int xx = x*x;
for (int y = 1; y < sqrtLimit; y++) {
int yy = y*y;
int n = 3*xx + yy;
if (n <= limit && n % 12 == 7) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
n += xx;
if (n <= limit && (n % 12 == 1 || n % 12 == 5)) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
if (x > y) {
n -= xx + 2*yy;
if (n <= limit && n % 12 == 11) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
}
}
}
for (int n = 5; n < limit; n++) {
if (primes[n] == 1) {
for (int k = n*n; k < limit; k += n*n) {
primes[k] = 0;
}
}
}
initialPrimes = intAlloc(2);
if (limit >= 2) {
initialPrimes[counter++] = 2;
}
if (limit >= 3) {
initialPrimes[counter++] = 3;
}
filtered = intFilterArrayKeys(primes, limit+1);
results = intMergeArrays(initialPrimes, filtered, counter, trueCount(primes, limit+1));
resultsSize = counter + trueCount(primes, limit+1);
free(primes);
free(initialPrimes);
free(filtered);
results[resultsSize] = 0;
return results;
}
int trueCount(int *subject, int arraySize) {
int count = 0;
for (int i = 0; i < arraySize; i++) {
if (subject[i] == 1) {
count++;
}
}
return count;
}
int intCount(int *subject) {
// warning: expects 0 terminated array.
int count = 0;
while (*subject++ != 0) {
count++;
}
return count;
}
void intFillArray(int *subject, int arraySize, int value) {
for (int i = 0; i < arraySize; i++) {
subject[i] = value;
}
}
int *intFilterArrayKeys(int *subject, int arraySize) {
int *filtered;
int count = 0;
filtered = intAlloc(trueCount(subject, arraySize));
for (int i = 0; i < arraySize; i++) {
if (subject[i] == 1) {
filtered[count++] = i;
}
}
return filtered;
}
int *intMergeArrays(int *subject1, int *subject2, int arraySize1, int arraySize2) {
int *merge;
int count = 0;
merge = intAlloc(arraySize1 + arraySize2);
for (int i = 0; i < arraySize1; i++) {
merge[count++] = subject1[i];
}
for (int i = 0; i < arraySize2; i++) {
merge[count++] = subject2[i];
}
return merge;
}
int *intAlloc(int amount) {
int *ptr;
ptr = (int *)malloc(amount * sizeof(int));
if (ptr == NULL) {
printf("Error: NULL pointer\n");
}
return ptr;
}
void printOutput(int num1, int num2, int rep) {
if (num1 == 0) {
printf("%d: No solution\n", rep);
exit(0);
} else {
printf("%d = %d + %d\n", rep, num1, num2);
}
}
Since you are still omitting some source, I can only imagine that the problem is hidden there.
EDIT: (my last update)
To assist your debugging, you should replace your main() function by the one below:
int main(int argc, char **argv)
{
int *primes = NULL;
primes = atkinsPrimes(44); // Evil magic number
free(primes);
return 0;
}
Having a minimal example to reproduce the behavior you pointed out is much better then the whole thing. Have fun with atkinsPrimes(44)

Resources