Segmentation fault in function implementing Ford-Fulkerson - c

I'm working on a class assignment and I've run into an issue I haven't been able to figure out. I'm implementing the Ford-Fulkerson algorithm using BFS to find max flow. But while trying to set my Residual Capacity matrix to the given capacity, I hit a segmentation fault. In the test code we received, I can see that the original capacity matrix was passed by value by its address, but I have a feeling that in my code I'm not interacting with it the way I think I am? Which leads me to believe that I may have the same issue recurring elsewhere. I worked with gdb and saw that I hit a segmentation fault on this line here in my nested for loop :
resCap[i][j] = *(capacity + i*n + j);
However, nothing I have tried has worked for me though so I am pretty stumped.
void maximum_flow(int n, int s, int t, int *capacity, int *flow)
{
int i, j, resCap[n][n], path[n]; // residual capacity and BFS augmenting path
int min_path = INT_MAX; // min of the augmenting path
// Assign residual capacity equal to the given capacity
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
{
resCap[i][j] = *(capacity + i*n + j);
*(flow + i*n + j) = 0; // no initial flow
}
// Augment path with BFS from source to sink
while (bfs(n, s, t, &(resCap[0][0]), path))
{
// find min of the augmenting path
for (j = t; j != s; j = path[j])
{
i = path[j];
min_path = min(min_path, resCap[i][j]);
}
// update residual capacities and flows on both directions
for (j = t; j != s; j = path[j])
{
i = path[j];
if(*(capacity + i*n + j) > 0)
*(flow + i*n + j) += min_flow_path;
else
*(flow + j*n + i) -= min_flow_path;
resCap[i][j] -= min_flow_path;
resCap[j][i] += min_flow_path;
}
}
}
And here is the test code provided to us in case it is needed:
int main(void)
{ int cap[1000][1000], flow[1000][1000];
int i,j, flowsum;
for(i=0; i< 1000; i++)
for( j =0; j< 1000; j++ )
cap[i][j] = 0;
for(i=0; i<499; i++)
for( j=i+1; j<500; j++)
cap[i][j] = 2;
for(i=1; i<500; i++)
cap[i][500 + (i/2)] =4;
for(i=500; i < 750; i++ )
{ cap[i][i-250]=3;
cap[i][750] = 1;
cap[i][751] = 1;
cap[i][752] = 5;
}
cap[751][753] = 5;
cap[752][753] = 5;
cap[753][750] = 20;
for( i=754; i< 999; i++)
{ cap[753][i]=1;
cap[i][500]=3;
cap[i][498]=5;
cap[i][1] = 100;
}
cap[900][999] = 1;
cap[910][999] = 1;
cap[920][999] = 1;
cap[930][999] = 1;
cap[940][999] = 1;
cap[950][999] = 1;
cap[960][999] = 1;
cap[970][999] = 1;
cap[980][999] = 1;
cap[990][999] = 1;
printf("prepared capacity matrix, now executing maxflow code\n");
maximum_flow(1000,0,999,&(cap[0][0]),&(flow[0][0]));
for(i=0; i<=999; i++)
for(j=0; j<=999; j++)
{ if( flow[i][j] > cap[i][j] )
{ printf("Capacity violated\n"); exit(0);}
}
flowsum = 0;
for(i=0; i<=999; i++)
flowsum += flow[0][i];
printf("Outflow of 0 is %d, should be 10\n", flowsum);
flowsum = 0;
for(i=0; i<=999; i++)
flowsum += flow[i][999];
printf("Inflow of 999 is %d, should be 10\n", flowsum);
printf("End Test\n");
}

This line is likely going to segfault, it does using Clang.
int i, j, resCap[n][n], path[n];
You're declaring a very large array on the stack. Just how big can be seen when you try and allocated it using calloc. Try this instead and don't forget to free it using the same sort of loop.
int **resCap2 = calloc(1, n * sizeof(int *));
assert(resCap2);
for (i = 0; i < n; i++) {
resCap2[i] = calloc(1, n * sizeof(int));
assert(resCap2[i]);
}
This is a lot of space ie
(1000 * sizeof(int*) * (1000 * n * sizeof(int)))

Related

As a result of processing arrays -nan(ind)

I am writing a program that creates arrays of a given length and manipulates them. You cannot use other libraries.
First, an array M1 of length N is formed, after which an array M2 of length N is formed/2.
In the M1 array, the division by Pi operation is applied to each element, followed by elevation to the third power.
Then, in the M2 array, each element is alternately added to the previous one, and the tangent modulus operation is applied to the result of addition.
After that, exponentiation is applied to all elements of the M1 and M2 array with the same indexes and the resulting array is sorted by dwarf sorting.
And at the end, the sum of the sines of the elements of the M2 array is calculated, which, when divided by the minimum non-zero element of the M2 array, give an even number.
The problem is that the result X gives is -nan(ind). I can't figure out exactly where the error is.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
const int A = 441;
const double PI = 3.1415926535897931159979635;
inline void dwarf_sort(double* array, int size) {
size_t i = 1;
while (i < size) {
if (i == 0) {
i = 1;
}
if (array[i - 1] <= array[i]) {
++i;
}
else
{
long tmp = array[i];
array[i] = array[i - 1];
array[i - 1] = tmp;
--i;
}
}
}
inline double reduce(double* array, int size) {
size_t i;
double min = RAND_MAX, sum = 0;
for (i = 0; i < size; ++i) {
if (array[i] < min && array[i] != 0) {
min = array[i];
}
}
for (i = 0; i < size; ++i) {
if ((int)(array[i] / min) % 2 == 0) {
sum += sin(array[i]);
}
}
return sum;
}
int main(int argc, char* argv[])
{
int i, N, j;
double* M1 = NULL, * M2 = NULL, * M2_copy = NULL;
double X;
unsigned int seed = 0;
N = atoi(argv[1]); /* N равен первому параметру командной строки */
M1 = malloc(N * sizeof(double));
M2 = malloc(N / 2 * sizeof(double));
M2_copy = malloc(N / 2 * sizeof(double));
for (i = 0; i < 100; i++)
{
seed = i;
srand(i);
/*generate*/
for (j = 0; j < N; ++j) {
M1[j] = (rand_r(&seed) % A) + 1;
}
for (j = 0; j < N / 2; ++j) {
M2[j] = (rand_r(&seed) % (10 * A)) + 1;
}
/*map*/
for (j = 0; j < N; ++j)
{
M1[j] = pow(M1[j] / PI, 3);
}
for (j = 0; j < N / 2; ++j) {
M2_copy[j] = M2[j];
}
M2[0] = fabs(tan(M2_copy[0]));
for (j = 0; j < N / 2; ++j) {
M2[j] = fabs(tan(M2[j] + M2_copy[j]));
}
/*merge*/
for (j = 0; j < N / 2; ++j) {
M2[j] = pow(M1[j], M2[j]);
}
/*sort*/
dwarf_sort(M2, N / 2);
/*sort*/
X = reduce(M2, N / 2);
}
printf("\nN=%d.\n", N);
printf("X=%f\n", X);
return 0;
}
Knowledgeable people, does anyone see where my mistake is? I think I'm putting the wrong data types to the variables, but I still can't solve the problem.
Replace the /* merge */ part with this:
/*merge*/
for (j = 0; j < N / 2; ++j) {
printf("%f %f ", M1[j], M2[j]);
M2[j] = pow(M1[j], M2[j]);
printf("%f\n", M2[j]);
}
This will print the values and the results of the pow operation. You'll see that some of these values are huge resulting in an capacity overflow of double.
Something like pow(593419.97, 31.80) will not end well.

Runtime error on hackerrank problems for no reason?

This is the question:
https://www.hackerrank.com/challenges/lisa-workbook/problem.
My code passes all the test cases except one. The message I get is just Run Time Error. Even if I return 0 at the beginning of the function that I am supposed to implement, I still get this error, while in all other test cases I get Wrong Answer.
This is not the only question on hacker rank where this happened. In the last couple of days I encountered 3 or 4 more questions with that one odd case that was always giving a runtime error. In the end, I had to implement a Python 3 solution (with the same logic), which passed all the test cases, to solve these problems.
I wonder if this is a bug on the website or if I am understanding something wrongly. Here is my function implementation for this problem:
int workbook(int n, int k, int arr_count, int* arr)
{
int tmp = 1, specprob = 0;
int *chstart = malloc(n * sizeof(int));
int *chend = malloc(n * sizeof(int));
for (int i = 0; i < n; i++) {
chstart[i] = tmp;
tmp += arr[i] / k - 1;
if (arr[i] % k != 0) {
tmp++;
}
chend[i] = tmp;
tmp++;
if (!(arr[i] < chstart[i])) {
int qno = 0, chpage = 1, iqno = 0;
for (int j = chstart[i]; j < chend[i] + 1; j++) {
if (chpage * k <= arr[i]) {
qno += k;
} else {
qno += (k - (chpage * k - arr[i]));
}
if (j > iqno && j < qno + 1) {
specprob++;
}
iqno = qno;
chpage++;
}
}
}
return specprob;
}
It looks like a bug, since when you run the empty function with just a return 0; it gives the same runtime error.
For the moment though, if you don't mind too much about the different language, you could make a few minor changes to the code to make it compile for C++ (don't forget to change the language selection too):
int workbook(int n, int k, vector<int> arr)
{
int tmp = 1, specprob = 0;
int *chstart = (int*)malloc(n * sizeof(int));
int *chend = (int*)malloc(n * sizeof(int));
for (int i = 0; i < n; i++)
{
chstart[i] = tmp;
tmp += arr[i] / k - 1;
if (arr[i] % k != 0)
{
tmp++;
}
chend[i] = tmp;
tmp++;
if (!(arr[i] < chstart[i]))
{
int qno = 0, chpage = 1, iqno = 0;
for (int j = chstart[i]; j < chend[i] + 1; j++)
{
if (chpage * k <= arr[i])
{
qno += k;
}
else
{
qno += (k - (chpage * k - arr[i]));
}
if (j > iqno && j < qno + 1)
{
specprob++;
}
iqno = qno;
chpage++;
}
}
}
return specprob;
}

Array values changing without reason

This is my code for Project Euler: Problem 11
int main(int argc, char** argv) {
char stevila [1600] = "08022297381500400075040507785212507791084949994017811857608717409843694804566200814931735579142993714067538830034913366552709523046011426924685601325671370236912231167151676389419236542240402866331380244732609903450244753353783684203517125032988128642367102638406759547066183864706726206802621220956394396308409166499421245558056673992697177878968314883489637221362309750076442045351400613397343133957817532822753167159403800462161409535692163905429635314755588824001754243629855786560048357189070544443744602158515417581980816805944769287392138652177704895540045208839735991607975732162626793327986688366887576220720346336746551232639353690442167338253911249472180846293240627636206936417230238834629969826759857404361620733529783190017431497148868116235705540170547183515469169233486143520189196748";
int stevilaGrid [20][20];
int stevilaRacunanje[4][4];
int stevecPoStevilih = 0;
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 20; j++) {
stevilaGrid[i][j] = (stevila[stevecPoStevilih] - 48)*10 + stevila[stevecPoStevilih + 1] - 48;
stevecPoStevilih += 2;
}
}
int rezultat [10];
int najvecji = 0;
int trenutni;
int temp = 0;
for (int i = 0; i < 17; i++) {
for (int j = 0; j < 17; j++) {
//problems start here
for (int k = 0; k < 5; k++) {
for (int l = 0; l < 5; l++) {
temp = stevilaGrid[i + k][j + l];
stevilaRacunanje[k][l] = temp;
}
}
for (int k = 0; k < 5; k++) {
rezultat[k] = stevilaRacunanje[k][0] * stevilaRacunanje[k][1] * stevilaRacunanje[k][2] * stevilaRacunanje[k][3];
rezultat[k+4] = stevilaRacunanje[0][k] * stevilaRacunanje[1][k] * stevilaRacunanje[2][k] * stevilaRacunanje[3][k];
}
rezultat[8] = stevilaRacunanje[0][0] * stevilaRacunanje[1][1] * stevilaRacunanje[2][2] * stevilaRacunanje[3][3];
rezultat[9] = stevilaRacunanje[0][3] * stevilaRacunanje[1][2] * stevilaRacunanje[2][1] * stevilaRacunanje[3][0];
for (int k = 0; k < 10; k++) {
trenutni = rezultat[k];
if(trenutni > najvecji){
najvecji = trenutni;
}
}
}
}
printf("Najvecji zmnozek: %d", najvecji);
return (EXIT_SUCCESS);
}
First I convert the string of numbers into a 2D int array.
Then I try to divide the grid into smaller 4x4 squares with which I can work more easily. That is where the problems start (as marked in the code).
At the very beginning (*i=0,j=0;k=4,j=0*) something strange starts to happen. The values in *stevilaGrid[][]* start to change randomly and seemingly without a reason.
Can somebody please explain this to me. I have tested this behavior on Windows with Cygwin 64bit and Ubuntu with GCC 64bit.
[i + k][j + l];
When i==16 and k==4 or j==16 and j==4 you'll be hitting element [20]
Your array only goes 0...19

Selection Sort using pointers

I have the following code:
void sortStrings(char strings[5][32])
{
int i = 0, j = 0, wall = 0;
int min = i;
for (int i = wall; i < 5; i++){
min = i;
for (j = wall; j < 5; j++){
if (strcmp(strings[j], strings[min]) < 0){
min = j;
}
}
swapStrings(strings[min], strings[wall]);
wall++;
}
}
What this code does is sorts a 2d array of strings by alphabetical order, I have tested it and it works correctly, now my question is how could I implement this code WITHOUT using array operations (aka using pointers and pointer operations only).
This is what I have so far and it is crashing when I try to run it so what am I doing wrong?
{
int i = 0, j = 0, wall = 0;
char *p = strings;
int min;
for (i = wall; i < 5; i++){
min = i;
for (j = wall; j < 5; j++){
if (*(p + j) < *(p + min)){
min = j;
}
}
swapStrings(*(p + j),*(p + wall));
wall++;
}
}
Here is the swapStrings method I am using for reference:
void swapStrings(char string1[], char string2[])
{
char temp[32];
strcpy(temp, string1);
strcpy(string1, string2);
strcpy(string2, temp);
}
The expected output is: if I were to enter in 5 strings, lets say they are:
hello
goodbye
how
are
you
It should return:
are
goodbye
hello
how
you
Thank you.
You have two things wrong:
p have to be char** and not char*
Comparing yourself between strings need a loop such:
int t = 0;
while (*(*(p + j)+t) && (*(*(p + j) + t) == *(*(p + min) + t)))
t++;
if (*(*(p + j) + t) < *(*(p + min) + t)) {
min = j;
}
Maybe you want to write your function for compare.

Cost function not decreasing in gradient descent implementation

I am trying implemented batch gradient descent in C language. The problem is, my cost function increases dramatically in every turn and I am not able to understand what is wrong. I checked my code several times and it seems to me that I coded exactly the formulas. Do you have any suggestions or ideas what might be the wrong in the implementation?
My data set is here: https://archive.ics.uci.edu/ml/datasets/Housing
And I reference these slides for the algorithm (I googled this): http://asv.informatik.uni-leipzig.de/uploads/document/file_link/527/TMI04.2_linear_regression.pdf
I read the data set correctly into the main memory. Below part shows how I store the data set information in main memory. It is straight-forward.
//Definitions
#define NUM_OF_ATTRIBUTES 13
#define NUM_OF_SETS 506
#define LEARNING_RATE 0.07
//Data holder
struct data_set_s
{
double x_val[NUM_OF_SETS][NUM_OF_ATTRIBUTES + 1];
double y_val[NUM_OF_SETS];
double teta_val[NUM_OF_ATTRIBUTES + 1];
};
//RAM
struct data_set_s data_set;
Teta values are initialized to 0 and x0 values are initialized to 1.
Below section is the hypothesis function, which is the standart polynomial function.
double perform_hypothesis_a(unsigned short set_index)
{
double result;
int i;
result = 0;
for(i = 0; i < NUM_OF_ATTRIBUTES + 1; i++)
result += data_set.teta_val[i] * data_set.x_val[set_index][i];
return result;
}
Below section is the cost function.
double perform_simplified_cost_func(double (*hypothesis_func)(unsigned short))
{
double result, val;
int i;
result = 0;
for(i = 0; i < NUM_OF_SETS; i++)
{
val = hypothesis_func(i) - data_set.y_val[i];
result += pow(val, 2);
}
result = result / (double)(2 * NUM_OF_SETS);
return result;
}
Below section is the gradient descent function.
double perform_simplified_gradient_descent(double (*hypothesis_func)(unsigned short))
{
double temp_teta_val[NUM_OF_ATTRIBUTES + 1], summation, val;
int i, j, k;
for(i = 0; i < NUM_OF_ATTRIBUTES + 1; i++)
temp_teta_val[i] = 0;
for(i = 0; i < 10; i++) //assume this is "while not converged"
{
for(j = 0; j < NUM_OF_ATTRIBUTES + 1; j++)
{
summation = 0;
for(k = 0; k < NUM_OF_SETS; k++)
{
summation += (hypothesis_func(k) - data_set.y_val[k]) * data_set.x_val[k][j];
}
val = ((double)LEARNING_RATE * summation) / NUM_OF_SETS);
temp_teta_val[j] = data_set.teta_val[j] - val;
}
for(j = 0; j < NUM_OF_ATTRIBUTES + 1; j++)
{
data_set.teta_val[j] = temp_teta_val[j];
}
printf("%lg\n ", perform_simplified_cost_func(hypothesis_func));
}
return 1;
}
While it seems correct to me, when I print the cost function at the end of the every gradient descent, it goes like: 1.09104e+011, 5.234e+019, 2.51262e+028, 1.20621e+037...

Resources