C : Runtime Error Verdict (Help debugging) - c

I am working on a problem on an Online Judge ( link here ), and I keep getting a runtime error verdict each time I submit my solution. I have been looking at it for a while now, I still can't figure out what's wrong with it. I have also looked up the typical reasons behind a runtime error (arrays out of bonds, memory limit exceeded, logical errors ... ect). I can't find any of them in the code posted below :
#include<stdio.h>
int Hall[110][110];
int isValid(int x, int y){
int i,j,cnt=0;
for(i=x-1; i<=x+1; i++)
for(j=y-1; j<=y+1; j++)
if(Hall[x][y]==Hall[i][j])
cnt++;
if(cnt>1)
return 0;
else
return 1;
}
int notChecked(int N,int* checked,int size){
int i;
for(i=0; i<size; i++)
if(checked[i] == N)
return 0;
return 1;
}
int main (void){
int T,R,C,checked[110],i,j,k,size;
scanf("%d",&T);
for(i=0; i<T; i++){
scanf("%d %d",&R,&C);
//initialize
size=0;
for(j=0; j<R*C; j++) checked[j] = -1;
for(j=0; j<=C+1; j++){
Hall[0][j] = -1;
Hall[R+1][j] = -1;
}
for(j=0; j<=R+1; j++){
Hall[j][0] = -1;
Hall[j][C+1] = -1;
}
//read input
for(j=1; j<=R; j++)
for(k=1; k<=C; k++)
scanf("%d",&Hall[j][k]);
//algo:
for(j=1; j<=R; j++)
for(k=1; k<=C; k++)
if(Hall[j][k]>=0){
if(notChecked(Hall[j][k],checked,size)){
if(isValid(j,k)==0){
checked[size] = Hall[j][k];
size++;
}
}
}
printf("%d\n",size);
}
return 0;}
Any help is much appreciated !

You need to do bounds checking on your input.
According to the site T needs to be between 1 and 100 inclusive, so you need to check for that. Then for each R and C (N and M on the site), they also need to be between 1 and 100 inclusive.
For each set of R by C entries, you need to make sure you actually read in R rows and C columns. You also need to ensure that you read in T total sets of entries.

Problem Solved !
The code contained an array out of bonds problem, in the following line:
for(j=0; j<R*C; j++) checked[j] = -1;
Knowing that checked had a size of 110 and R and C a max size of 100 each. I changed the size of checked to 10100 and it worked.
Thanks #chux for the help !

Related

For Loops Based on User Input in C

I have different paths that are predefined in a 2-D array as [seed][sequence] with 'seed' being the path (0-255) and 'sequence' being the index in the path (0-49). Is there a way to neatly compare an input-defined number of paths at once when the number of paths compared may vary from run to run?
How my input is gathered:
#define MAX 250
int numUsers; //the number of users
int users[MAX][2]; //each user and their respective seed
int collisions = 0; //number of collisions
static inline void compareNumUsers(){
printf("Enter the number of users: ");
scanf("%d", &numUsers);
printf("\n");
for(int i = 0; i < numUsers; i++){
printf("Enter the seed of user%d [0-255]: ", i+1);
scanf("%d", &users[i][1]);
}
}
Best case scenario the answer is not a series of case-switch statements
I am hoping that something to the effect of this will be possible:
(assume 3 given inputs)
for(int j = 0; j < pathLength; j++){
if(paths[users[0][1]][j] == paths[users[1][1]][j] || paths[users[1][1]][j] == paths[users[2][1]][j] || paths[users[2][1]][j] == paths[users[0][1]][j])
collisions++;
}
I would be lying if I said I did not confuse myself when thinking how to even ask this question so if you are confused by something please ask me to verify I will not be offended.
The comparison also does not have to be in the same manner that I provided, it is just how I presently think about it.
Any help is appreciated. Thank you in advance.
Use nested loops to compare all the pairs.
for (int j = 0; j < pathlength; j++) {
for (int i = 0, broken = 0; !broken && i < numUsers - 1; i++) {
for (int k = i + 1; k < numUsers; k++) {
if (paths[users[i][1]][j] == paths[users[k][1]][j]) {
collisions++;
broken = 1;
break;
}
}
}
}

managing memory in C, 2D float array

I'm very inexperienced with C and have to use it for a piece of coursework exploring heat transfer.
I'm getting all sorts of errors with the (0xC0000005) return code. I'm aware that this is an attempt to access memory out of bounds and that I'm probably failing to allocate memory properly somewhere but I haven't been able to figure it out.
Any idea what needs changing?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(){
/* constant alpha squared, the area of the domain */
const float alphSqrd = 0.01;
const float deltX, deltY = 0.0002;
const float timeStep = 0.0000009;
const int maxTimeSteps = 1000;
int h, i, j;
/* 2D Array of Temperature Values */
float T [500][500];
float dTdt;
/* initialise temperature values */
printf("Initialising 2D array...\n");
for (i=0; i<500; i++){
for (j=0; j<500; j++){
if (150<=i && i<350 && 150<=j && j<350){
T[i][j] = 50;
} else {
T[i][j] = 20;
}
}
}
printf("Updating values...\n");
for (h=0; h<maxTimeSteps; h++){
for (i=0; i<500; i++){
for (j=0; j<500; j++){
dTdt = alphSqrd*(((T[i+1][j]-2*T[i][j]+T[i-1][j])/(deltX*deltX))+((T[i][j+1]-2*T[i][j]+T[i][j-1])/(deltY*deltY)));
T[i][j] = T[i][j] + dTdt * timeStep;
printf("%f ",T[i][j]);
}
printf("\n");
}
}
return 0;
}
Although that's not the problem you're describing, one issue is that you're not initializing deltX. Instead of this
const float deltX, deltY = 0.0002;
you want
const float deltX = 0.0002 , deltY = 0.0002;
Aside from that, you have an out of range issue. If you're going to access index i - 1 and i + 1, you can't loop from 0 to 499 on an array of 500 elements.
It works for me if I adjust the loops like this:
for (i = 1; i < 499; i++) {
for (j = 1; j < 499; j++) {
During your dTdt calculation you are using T[i-1][j] and T[i-1][j]. If i is maximal (0 or 500) this exceeds the array limits. The same holds for j.
Thus, you use uninitialised memory. You need to loop form 1 to 499 and treat the boundary differently depending on the problem you are trying to solve.
Firstly adjust the loop min and max values;
for (i=1; i<499; i++){
for (j=1; j<499; j++){
And you should make comment line to printf(). stdout takes much time in the loop.
for (h=0; h<maxTimeSteps; h++){
for (i=1; i<499; i++){
for (j=1; j<499; j++){
dTdt = alphSqrd*(((T[i+1][j]-2*T[i][j]+T[i-1][j])/(deltX*deltX))+((T[i][j+1]-2*T[i][j]+T[i][j-1])/(deltY*deltY)));
T[i][j] = T[i][j] + dTdt * timeStep;
//printf("%f ",T[i][j]);
}
//printf("\n");
}
}
I compiled this code on my virtual Linux and it took nearly 3 seconds.
enter image description here

How to avoid SIGSEGV Error in Insertion Sort

I am trying to implement Insertion sort algorithm in C.
But all I get is SIGSEGV error in online IDEs and the output doesn't show up in Code::Blocks. How to avoid Such errors.
#include <stdio.h>
#include <stdlib.h>
int main()
{
/* Here i and j are for loop counters, temp for swapping
count for total number of elements,array for elements*/
int i, j, temp, count;
printf("How many numbers are you going to enter");
scanf("%d", &count);
int n[20];
printf("Enter %d elements", count);
// storing elements in the array
for(i = 0; i < count; i++) {
scanf("%d", n[i]);
}
// Implementation of insertion sort algorithm
for(i = 0; i < count; i++) {
temp = n[i];
j = i - 1;
while(temp < n[j]) {
n[j+1] = n[j];
j = j - 1;
}
n[j+1] = temp;
}
printf("Order of sorted elements");
for(i = 0; i < count; i++) {
printf("%d", n[i]);
}
return 0;
}
There are a couple of problems with your code. First of all, what is a SIGSEGV error? Well, it's another name for the good old Segmentation fault error, which is basically the error you get when accessing invalid memory (that is, memory you are not allowed to access).
tl;dr: change scanf("%d",n[i]); to scanf("%d",&n[i]);. You're trying to read the initial values with scanf("%d",n[i]);, this raises a segmentation fault error because scanf expects addresses in which put the values read, but what you're really doing is passing the value of n[i] as if it were an address (which it's not, because, as you did not set any value for it yet, it's pretty much just memory garbage). More on that here.
tl;dr: change int n[20]; to int n[count]. Your array declaration int n[20]; is going to store at most 20 integers, what happens if someone wants to insert 21 or more values? Your program reserved a certain stack (memory) space, if you exceed that space, then you're going to stumble upon another program's space and the police (kernel) will arrest you (segmentation fault). Hint: try inserting 21 and then 100 values and see what happens.
tl;dr: change for(i = 0; i < count; i++) { to for(i = 1; i <= count; i++) {. This one is a logic problem with your indexes, you are starting at i = 0 and going until i = count - 1 which would be correct in most array iteration cases, but as j assumes values of indexes before i, you need i to start from 1 (so j is 0, otherwise j = -1 in the first iteration (not a valid index)).
My final code is as follows. Hope it helped, happy coding!
#include <stdio.h>
#include <stdlib.h>
int main() {
/*Here i and j are for loop counters,temp for swapping
count for total number of elements,array for elements*/
int i, j, temp, count;
printf("How many numbers are you going to enter?\n");
scanf("%d",&count);
int n[count];
printf("Enter %d elements\n",count);
//storing elements in the array
for(i = 0; i < count; i++) {
scanf("%d", &n[i]);
}
//Implementation of insertion sort algorithm
for(i = 1; i <= count; i++) {
temp = n[i];
j = i-1;
while(temp < n[j]) {
n[j+1] = n[j];
j--;
}
n[j+1] = temp;
}
printf("Order of sorted elements\n");
for(i = 0; i < count; i++) {
printf("%d\n",n[i]);
}
return 0;
}
Edit: If you're having trouble with online IDEs, consider running your programs locally, it saves a lot of time, plus: you never know what kernel version or magic the online IDEs are using to run your code (trust me, when you're coding in C -- fairly low level language, these things make a difference sometimes). I like to go all root style using Vim as text editor and gcc for compiling as well as gdb for debugging.

Why is my program not sorting the struct?

I am trying to create this program that takes an int number from the user then randomizes a pair of numbers, based on the input, inside the an array of struct. Then it sorts this array based on the sum of the number pair the program randomized.
However my program won´t sort the array of struct. It doesn´t do the sorting properly and Im not sure why. Here is the code.
#define MAX 10
struct NumPair{
int n,m;
};
int main()
{
int i, j, amount=0;
NumPair NumPair[MAX];
srand(time(NULL));
printf("How many pair of numbers? (max 10): ");
scanf("%d", &amount);
for (i=0; i<amount; i++)
{
NumPair[i].n = rand() % 11;
NumPair[i].m = rand() % 11;
}
for (i=0; i<amount; i++)
{
for(j=1; j<amount; j++)
{
if( (NumPair[i].n+NumPair[i].m) > (NumPair[j].n+NumPair[j].m) )
{
int tmp;
tmp = NumPair[i].n;
NumPair[i].n = NumPair[j].n;
NumPair[j].n = tmp;
tmp = NumPair[i].m;
NumPair[i].m = NumPair[j].m;
NumPair[j].m = tmp;
}
}
}
for (i=0; i<amount; i++)
{
printf(" NumPair %d: (%d,%d)\n", i+1, NumPair[i].n, NumPair[i].m);
}
return 0;
}
What am I missing? It's probably something very silly.
Thanks in advance.
Your algorithm is incorrect. This little snippet:
for (i=0; i<amount; i++) {
for(j=1; j<amount; j++) {
will result in situations where i is greater than j and then you comparison/swap operation is faulty (it swaps if the i element is greater than the j one which, if i > j, is the wrong comparison).
I should mention that (unless this is homework or some other education) C has a perfectly adequate qsort() function that will do the heavy lifting for you. You'd be well advised to learn that.
If it is homework/education, I think I've given you enough to nut it out. You should find the particular algorithm you're trying to implement and revisit your code for it.
You are comparing iterators i with j. Bubble sort should compare jth iterator with the next one
for (i=0; i<amount; i++) //pseudo code
{
for(j=0; j<amount-1; j++)
{
if( NumPair[j] > NumPair[j+1] ) //compare your elements
{
//swap
}
}
}
Note that the second loop will go only until amount-1 since you don't want to step out of bounds of the array.
change to
for (i=0; i<amount-1; i++){
for(j=i+1; j<amount; j++){

why is my 3n+1 problem solution wrong

I have recently started reading "Programming Challenges" book by S. Skiena and believe or not I am kind of stuck in the very first problem.
Here's a link to the problem: 3n+1 problem
Here's my code:
#include <stdio.h>
long get_cycle(long input){
if (input == 1){
return 1;
}
else{
if (input & 1){
return 2 + get_cycle((3*input+1)>>1);
}
else{
return 1 + get_cycle(input >> 1);
}
}
}
long get_range_cycle(int k, int j){
int i;
int max = 0;
int current_cycle;
int to = k > j ? k : j;
int from = k < j ? k : j;
for (i=from; i<=to; ++i){
current_cycle = get_cycle(i);
if (current_cycle > max){
max = current_cycle;
}
}
return max;
}
int main(){
long p, q;
long re[100][3];
int i = 0;
while (scanf("%ld %ld",&p,&q) == 2){
re[i][0] = p;
re[i][1] = q;
re[i][2] = get_range_cycle(p,q);
++i;
}
int j;
for (j=0; j<i; ++j){
printf("%ld %ld %ld\n",re[j][0],re[j][1],re[j][2]);
}
}
what is wrong with my code? the input and out is exactly the same with sample.But the submission result is always run time error!
You're code seems to assume maximum 100 lines in the input file - the sample data they are testing on might be bigger? They make no explicit claim wrt the maximum set size of the input data.
I believe that the problem you seek answer for is in the answer #Elemental . If you fix that, however, your solution will time out.
What you should do is to build up a list of all answers between 0 and 1000000. This can be done in linear time (I will not give you the full answer).

Resources