Weird error/result when running code... C fdtd method - c

Whenever I initiate a for loop to give values to an array, it modifies the result in another loop despite not being called in that loop... The problem comes from epsR... somehow commenting/uncommenting it changes the result for the time stepping loop (calculating the elec/mag field). Why? When the for loop with espR in and the if statement is left commented out, the results are good. When not commented out, I get nonsense results!
Could it be like memory corruption? I don't see what could be causing the problem.
#include <stdio.h>
#include <math.h>
#define SIZE 200
int main()
{
double ez[SIZE]={0.}, hy[SIZE]={0.}, imp0=377.0;
double epsR[SIZE];
int qTime, maxTime=650, mm;
char basename[80]="sim", filename[100];
int frame=0;
FILE *snapshot;
/* Init */
for (mm=0;mm<SIZE;mm++){
ez[mm]=0.0;
}
for (mm=0;mm<SIZE-1;mm++){
hy[mm]=0.0;
}
/* Leaving this loop uncommented modifies the results
of the loop time stepping*/
for (mm=0;mm<SIZE;mm++){
if (mm<100){
epsR[mm]=1.0;
}
else {
epsR[mm]=9.0;
}
}
/* time stepping*/
for (qTime=0; qTime<maxTime;qTime++){
/*Mag field*/
hy[SIZE-1]=hy[SIZE-2];
for (mm=0;mm<SIZE-1;mm++){
hy[mm]=hy[mm]+(ez[mm+1]-ez[mm])/imp0;
}
hy[49]-=exp(-(qTime-30.)*(qTime-30.)/100.)/imp0;
/*Elec field*/
ez[0]=ez[1];
ez[SIZE-1]=ez[SIZE-2];
for (mm=0;mm<SIZE;mm++){
ez[mm]=ez[mm]+(hy[mm]-hy[mm-1])*imp0/9.0;
}
ez[50]+=exp(-(qTime+0.5-(-0.5)-30.)*(qTime+0.5-(-0.5)-30.0)/100.);
/*Write*/
if (qTime % 10==0){
sprintf(filename,"%s.%d", basename, frame++);
snapshot=fopen(filename,"w");
for (mm=0;mm<SIZE;mm++){
fprintf(snapshot,"%g\n",ez[mm]);
}
fclose(snapshot);
}
}
return 0;
}

In this loop:
for (mm=0;mm<SIZE;mm++){
ez[mm]=ez[mm]+(hy[mm]-hy[mm-1])*imp0/9.0;
}
in the first iteration, mm == 0
so hy[mm-1] is hy[-1] and that's the out of bounds undefined behavior. Meaning anything can happen, because it's accessing random data.
If you want it to be accessing the last element, check like so:
for (mm=0;mm<SIZE;mm++){
if(mm==0) {
ez[0]=ez[0]+(hy[0]-hy[SIZE - 1])*imp0/9.0;
} else {
ez[mm]=ez[mm]+(hy[mm]-hy[mm-1])*imp0/9.0;
}
}

Related

C-How to increase in recursion?An example of recursively judging prime numbers

I'm a programming rookie who has not yet started. I just learned recursion and there are some problems with the use of recursion. There is a homework is judge prime numbers :using int prime(int x); and return boolean value.
Initially I found that because the variable is initialized and assigned inside the function,the program can't achieve self-increment. Because every time it enters a new level of recursion, the variable will be reassigned. Even if you write a variable auto-increment statement, it will only auto-increase the variables stored in the current recursive stack. Once the variable enters a new recursive level, the variable is only initialized according to the definition and cannot be continuously auto-incremented.
The solution to the failure is as follows:
#include <math.h>
#define false 0
#define true 1
int prime(int x){
double high=sqrt(x);
int low=2;
if((x%low==0 && x!=2) || low>high){
return false;
}
else if(x<2){
return false;
}
else{
return true;
}
low++;
return prime(x);
}
When asking questions, I found a successful solution:
#include <math.h>
#define false 0
#define true 1
int prime(int x){
double high=mysqrt(x);
static int low=2;
if((x%low==0 && x!=2)||low>high){
return false;
}
else if(x<2){
return false;
}
else{
return true;
}
low++;
return prime(x);
}
But I can't understand why using static to modify the variable can make the variable correctly increment when entering a new layer of recursion instead of executing the previous int low=2;
Ask the master to solve the confusion for me, what happened to the two in the memory space?
In addition, there seems to be another solution, which seems to be to set a flag variable, but I did not understand it. Can someone provide other solutions?
In a nutshell, ordinary variables (int low;) get created for each function call independently, while static (static int low = 2;) are created once and shared between all the functions.
However, static is not the best approach to use in such cases, because different function calls may need to have different values of high/low.
Instead, you may add explicit parameters to the function, something like this (the algorithm is wrong, but it's the general principle):
int prime(int x) { return prime_impl(x, 2, sqrt(x)); }
int prime_impl(int x, int low, double high) {
if(x<2) {
return false;
}
else if((x%low==0 && x!=2)||low>high) {
return true;
}
else {
return prime_impl(x, low+1, high);
}
}

C linear search failing to compare two strings using strcmp, compiles fine

The program runs and exits with code 0, but gives no output, it's supposed to be a linear search program
I looked to other similar problems, i tried to end the array with \n. tried instead of just relying in just the "if (strcmp=0)" to make something with the values strcmp return, I'm very new and for what I'm learning not very good, just made things worst, i tried to look if it was about the char* values strcmp expect, but couldn't find the problem
#include <stdio.h>
#include <string.h>
#define max 15
int lineal(char elementos[], char elebus)
{
int i = 0;
for(i=0; i<max; i++)
{
if(strcmp(elementos[i], elebus)==0)
{
printf("Elemento encontrado en %d,", i); //element found in
}
else
{
printf("elemento no encontrado"); //not found
}
}
}
int main()
{
char elebus[50];
char elementos[max][50]= {"Panque", "Pastel", "Gelatina", "Leche", "Totis", "Tamarindo" "Papas", "Duraznos", "Cacahuates", "Flan", "Pan", "Yogurt", "Café", "Donas", "Waffles"};
printf("Escribir elemento a buscar\n");
scanf("%s", elebus);
int lineal(char elementos[], char elebus);
}
The expected output would be element found in "i" position, if found
if not found print "not found"
You want to pass it a string to find, not just one character Also, elementos should be a 2D array. Change the signature of your function to this:
int lineal(char elementos[max][50], char *elebus)
Also, in main, you don't call the function. Instead, you just declare it again. call it like this:
lineal(elementos, elebus);
Furthermore, I would change it to return void instead of int. You're neither returning anything (that's undefined behavior) nor are you using the return value anywhere. But I assume that this isn't the final version and you want to return the index at some point.
On a side note, right now it's printing that it didn't find the element for every time it didn't match, even if it does find it eventually. I would recommend this instead:
for (i = 0; i < max; i++)
{
if (strcmp(elementos[i], elebus) == 0)
{
printf("Elemento encontrado en %d\n,", i); //element found in
return;
}
}
printf("elemento no encontrado\n"); //not found
This is printing "elemento no encontrado" only once, and only when the string wasn't found.

Read integer untill user reaches negative integer or numbers of integer reaches upto 15

i wrote following program but it is not right. would you please assist me where i went wrong?
#include<stdio.h>
void main()
{
int count=0,a;
do
{
scanf("%d",&a);
if(a>0 )
{
for(count=0;count<15;count++);
else;
}
while(int>=0);
}
So would you tell me the correct code?
Please use building blocks of correct syntax:
main:
#include <stdio.h>
int main(void)
{
/* other code */
return 0;
}
do-while:
do
{
/* other code */
} while(count>=0);
if:
if(a>0 )
{
/* code if true */
} else
{
/* code if false */
}
for:
for(a=0;a<15;a++)
{
/* repeated code */
}
For getting input right, please read:
http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html
How to read / parse input in C? The FAQ
When the syntax is right and the input is done correctly, then we can discuss the behaviour of your code; which I think is what you are actually asking about. Though what you are describing might already be solved/achieved once you spend some work on how to get input properly, based on the links above.

Why am I getting a "Segmentation Fault" error when I try to run the tests?

I've written a function that determines whether or not to assign default values (it assigns default values if the flag is not present, and it assigns values the user passes if the flag is present). And I'm trying to test my function with a string to see if it did give me the right numbers. I keep getting "Segmentation Fault" when I try to run the tests, it compiles, but the tests just don't work. :(
Here's my header file:
#ifndef COMMANDLINE_H
#define COMMANDLINE_H
#include "data.h"
#include <stdio.h>
struct point eye;
/* The variable listed above is a global variable */
void eye_flag(int arg_list, char *array[]);
#endif
Here's my implementation file:
#include <stdio.h>
#include "commandline.h"
#include "data.h"
#include "string.h"
/* Used global variables for struct point eye */
void eye_flag(int arg_list, char *array[])
{
eye.x = 0.0;
eye.y = 0.0;
eye.z = -14.0;
/* The values listed above for struct point eye are the default values. */
for (int i = 0; i <= arg_list; i++)
{
if (strcmp(array[i], "-eye") == 0)
{
sscanf(array[i+1], "%lf", &eye.x);
sscanf(array[i+2], "%lf", &eye.y);
sscanf(array[i+3], "%lf", &eye.z);
}
}
}
And here are my test cases:
#include "commandline.h"
#include "checkit.h"
#include <stdio.h>
void eye_tests(void)
{
char *arg_eye[6] = {"a.out", "sphere.in.txt", "-eye", "2.4", "3.5", "6.7"};
eye_flag(6, arg_eye);
checkit_double(eye.x, 2.4);
checkit_double(eye.y, 3.5);
checkit_double(eye.z, 6.7);
char *arg_eye2[2] = {"a.out", "sphere.in.txt"};
eye_flag(2, arg_eye2);
checkit_double(eye.x, 0.0);
checkit_double(eye.y, 0.0);
checkit_double(eye.z, -14.0);
}
int main()
{
eye_tests();
return 0;
}
The absolute easiest way to solve this one is run it in a debugger. You probably won't even need to learn how to step through your code or anything - just fire up, run, and read the line.
If you are on a *nix system:
Compile your code with -g flag.
Load as, e.g. gdb a.out.
Run now that it's loaded - (gdb) run.
Do whatever you need to reproduce the segfault.
bt or where should give you a stack trace - and an exact line that is causing your problem.
I'm sure enough you can solve it from there to post this as an answer; but if not, knowing the exact line will make it very much easier to research and solve.
The errors are here:
for (int i = 0; i <= arg_list; i++)
{ ///^^
if (strcmp(array[i], "-eye") == 0)
{
sscanf(array[i+1], "%lf", &eye.x);
//^^^
sscanf(array[i+2], "%lf", &eye.y);
sscanf(array[i+3], "%lf", &eye.z);
}
}
i <= arg_list is wrong since you pass in 6, array index starts from 0, the max value is 5
i+1, i+2,i+3 will give you out of bounds index when you iterate from 0 to 5.
Your loop condition is wrong. It should be i < arg_list.
Think about what happens when i == arg_list.

Calling a function more than once

So I'm programming a PIC using a CCS compliler. I'm using timer interrupt and this interrupt calls a function, called chronometer, that I wrote twice. This is how it goes
void timer2_isr()
{
j++;
l++;
z++;
if (j==1)
{
timero=1;
btndly=1;
j=0;
}
user1= chronometer(x, l);
user2= chronometer(pad.deger, z);
}
This function returns a struct and takes 2 integers as an argument. It works fine, when I just call the function once. However when, as in this case, I call the function twice, user2 is just equal to whatever user1 is and the code is not even working correctly. Any idea why?
chrono chronometer(int enable, int milicounter)
{
chrono time;
if(enable==1 && milicounter>=25) // Eğer kronometre aktif haldeyse
{
milicounter=0;
time.sec++;
if(time.sec==60)
{
time.sec=0;
time.min++;
}
if(time.min==60)
{
time.min=0;
time.hour++;
}
if(time.hour==24)
time.hour=0;
}
return time;
}
It seems you are starting to use the time struct without resetting it's members, resulting in unexpected results..
And even if it is somehow initialized.. it does not refer to the input parameters, so obviously the result will be the same..

Resources