I have this piece of code that gives me SEGMENTATION FAULT when the function loadRow(tmpPop,bestOf4Route,k,n); is called the fifth time. In particular, the function is called correctly at the first loop of the fro (when p=3). It' all ok for every value of k. I don't understand why, the second time I execute the loop (p=7), the first time is called (k=0), it return SEGMENTATION F when try to access the matric tmpPop.
randperm(popSize,randomOrder);
for(p = 3;p<popSize;p+=4)
{
load_rtes(rtes,pop,randomOrder,n,p);
load_dists(dists,totalDist,randomOrder,p);
find_min(dists, 4,&m,&idx);
for(j=0;j<n;j++) bestOf4Route[j]=rtes[j][idx];
X = rand_range(1,5);
Y = rand_range(1,5);
for(k =0;k<4;k++) //Mutate the Best to get Three New Routes
{
loadRow(tmpPop,bestOf4Route,k,n);
switch(k)
{
case 1: //Flip
flipMutation(tmpPop,k,X,Y);
break;
case 2: //Swap
swapMutation(tmpPop,k,X,Y);
break;
case 3: //Slide
slideMutation(tmpPop,k,X,Y);
break;
}
}
loadnewPop(newPop,tmpPop,p,n);
}
The function is:
void loadRow(int **mat,int *array,int k,int size)
{
int j;
for(j=0;j<size;j++)
{
mat[j][k] = array[j];
}
}
The parameters are:
popSize = 16
n= 8
// create 4 x N matrix
tmpPop = (int**)malloc(n * sizeof(int*));
if(tmpPop==NULL) return 1;
for (i = 0; i < n; i++) {
tmpPop[i] = (int*)malloc(4 * sizeof(int));
if(tmpPop[i]==NULL) return 1;
}
// Creates an array of n
bestOf4Route = (int*)malloc(n * sizeof(int));
if(bestOf4Route==NULL) return 1;
clear_array(bestOf4Route,n);
And her it is the debug result:
00401865 loadRow(mat=0x3e1438, array=0x3e1698, k=0, size=8)
void load_rtes(int **rtes,int **pop,int *randomOrder, int n,int p)
{
int i,j,r;
for(i=p-3;i<=p;i++)
{
//thakes the i element of randomOrder and use it as index for the pop row
r=randomOrder[i];
// copy the pop row in rtes
for(j=0;j<n;j++)
{
rtes[j][i]=pop[j][r];
}
}
}
void randperm(int n,int *perm)
{
int i, j, t;
for(i=0; i<n; i++)
perm[i] = i;
for(i=0; i<n; i++) {
j = rand()%(n-i)+i;
t = perm[j];
perm[j] = perm[i];
perm[i] = t;
}
}
A Segfault means that you accessed a memory region you weren't allowed to access. This can happen quite easily when doing pointer arithmetic wrong. So, although I can't tell you where the problem exactly lies, I suggest that you use a good debugger or some printf() statements to look at k, n and j to see if you exceed the bounds of the matrix / array. Also, you'll need to make sure that you allocated the right amount of memory.
Related
void interclas(int *ptr,int *vec, int *c, int n) {
int i,j,tmp;
tmp=0;
for (i=0;i++;i<n)
for (j=0;i++;j<n)
{
if (vec[j]<=ptr[i])
c[tmp]=vec[j];
else
c[tmp]=ptr[i];
tmp++;
}
}
int main() {
int i,n;
int *ptr,*vec,*c;
printf("Nr. of elements of initial arrays : 5 \n");
n=5;
vec=(int*)malloc( n * sizeof(int));
ptr=(int*)malloc( n * sizeof(int));
c=(int*)malloc( 2 * n * sizeof(int));
for (i=0;i<n;i++) {
scanf("%d",&ptr[i]);
}
for (i=0;i<n;i++) {
scanf("%d",&vec[i]);
}
printf("\n");
printf("Initial arrays are : ");
for (i=0;i<n;i++) {
printf("%d ",ptr[i]);
}
printf("\n");
for (i=0;i<n;i++) {
printf("%d ",vec[i]);
}
interclas(ptr,vec,&c,n);
printf("Merged array is : ");
for (i=0;i<10;i++) {
printf("%d ",c[i]);
}
return 0;
}
So I'm trying to merge two sorted arrays into one new one using pointers with the function 'interclas'. I tried using the same method to sort an array with a pointer in a function and it worked just fine. Now as you can see, it stores the adress of the variable rather than the variable itself.
If I run this, it stores the adresses of the arrays. How can I fix this? (I'm still new to pointers)
In your method's body, change:
for (i=0;i++;i<n)
for (j=0;i++;j<n)
to this:
for (i=0; i<n; i++)
for (j=0; j<n; j++)
and then change the call to your method, from this:
interclas(ptr, vec, &c, n);
to this:
interclas(ptr, vec, c, n);
since the prototype expects a pointer to an int, for the third parameter.
The logic of your method is also flawed, try to put some printfs (e.g. printf("here i = %d, j = %d, ptr[i] = %d, vec[j] = %d, tmp = %d\n", i, j, ptr[i], vec[j], tmp);) to see what values your variables have at its iteration - you only get the first two elements of the first array to be merged!
If you think about it, what you'd like to do is to go through the first element of array ptr and vec, and store the minimum of this two. If now that min was of array ptr, you'd like the next element of ptr to be taken into account, otherwise the next element of vec.
Take a pencil and a paper and sketch that algorithm - you'll see that it goes out nicely, but some leftover elements might be left behind, and not get inserted in the output array.
Driven from that observation, after traversing both the arrays and comparing elements, we will loop over the first array, if needed, to collect elements that were not visited. Similarly for the second array.
Coding that thought gives something like this:
void interclas(int *ptr,int *vec, int *c, int n) {
int i = 0, j = 0, tmp = 0;
// Traverse both arrays simultaneously,
// and choose the min of the two current elements.
// Increase the counter of the array who had
// the min current element.
// Increase the counter for the output array in
// any case.
while(i < n && j < n)
{
if(ptr[i] < vec[j])
{
c[tmp++] = ptr[i++];
}
else
{
c[tmp++] = vec[j++];
}
}
// Store remaining elements of first array
while (i < n)
c[tmp++] = ptr[i++];
// Store remaining elements of second array
while (j < n)
c[tmp++] = vec[j++];
}
Not the source of your problem, but Do I cast the result of malloc? No.
C language
I want to compare an array with it's reversed form and check to see if it's the same.
For example, arr1 = 5 5 8 8 5 5
Reversed arr1 = 5 5 8 8 5 5
Then output would be: Array is the same in reverse.
For some reason when I try to compare my two arrays, it ALWAYS says it is the same even if it is not.
For example : 7 8 9 is entered. The reverse is 9 8 7, which is not the same as what was entered. However, my code says it is.
How can I fix my comparison so that the results are accurate? Please advise, thank you!
I tried using goto to display results. This is my code (function):
void function(int *arr)
{
int j, c, temp, size;
size = sizeof(arr);
int old[size];
int new[size];
/*Prints original array from user input*/
printf("Input Array: ");
for(j=0; j<size; j++)
{
printf("%d ", arr[j]);
old[j] = arr[j];
}
printf("\n");
/* Reversing the array */
c = j - 1;
j = 0;
while (j < c)
{
temp = arr[j];
arr[j] = arr[c];
arr[c] = temp;
j++;
c--;
}
/* Print Reversed Array */
int i;
for(i=0; i<size; i++)
{
printf("%d ", arr[i]);
/*saved to new for possible comparison*/
new[i] = arr[i];
}
printf("\n");
/* Compare original array with reversed array */
if(temp = arr[j])
{
goto same;
} else {
goto notsame;
}
same:
printf("Array is the same in reverse\n");
return 0;
notsame:
printf("Array is not the same in reverse\n");
return 0;
}
You can't get the size of the array with sizeof. You should print out size and see what that value is giving you, it won't be the size of the array.
The reason you are always getting the "same" is that you aren't actually comparing values. You are assigning arr[j] to temp. if(temp = arr[j]) should be if(temp == arr[j]). I think you will find that it won't go to same anymore.
An easier way to solve this problem would be:
void checkReverse(int* arr, int arrSize)
{
// Loop through the array until you have hit the middle
for (int i = 0; i < (arrSize - i); i++)
{
// Check the element to the element in the same place counting from the back
if (arr[i] != arr[arrSize - i - 1])
{
// If we find any that don't match, we know it's not the same and can return
printf("Array is NOT the same in reverse.\n");
return;
}
}
// If we made it this far, they are the same
printf("Array is the same in reverse.\n");
return;
}
You need to modify your code with the following two points:
In your code, size means the number of elements in the array correct? so to calculate it correctly replace
size = sizeof(arr)/sizeof(int);
sizeof gives you the memory size occupied by the array, so for the array of three integers, it gives 3*int size. To count the elements of an array you need to use sizeof(array) and divide it with the size of the data type.
You need to traverse in the loop and compare each element of the original array and reversed array to confirm is it the same not.
So you need to replace your comparison logic with :
/* Compare original array with reversed array */
for(i=0;i < size;i++)
{
if(new[i] != old[i]){
printf("Array is not the same in reverse\n");
return;
}
}
printf("Array is the same in reverse\n");
return;
If you want to use recursion to solve this problem.
#include <stdio.h>
int compare(int *arr, int p, int q)
{
/* base case, if we are at or pass the middle point */
if (p >= q)
return 1;
if (arr[p] != arr[q]) {
return 0;
} else {
return compare(arr, p + 1, q - 1);
}
}
int main(int argc, char *argv[])
{
int arr1[] = {5, 5, 8, 8, 5, 5};
size_t array_size = sizeof(arr1) / sizeof(int);
int first = 0;
int last = array_size - 1;
if (compare(arr1, first, last)) {
printf("Array is same in reverse\n");
} else {
printf("Array is not same in reverse\n");
}
return 0;
}
Best solution to this question during an interview IMO: Use a stack:
step 1)
racecar -> push into stack -> STACK
step 2)
STACK-> pop from stack -> racecar
The input and output strings are the same, therefore the word is a palindrome.
As opposed to:
step 1) something -> push into stack -> STACK
step 2) STACK-> pop from stack -> gnihtemos
The input and output strings are NOT the same, therefore the word is NOT a palindrome.
I've been trying to build a recursive function which calculates the max value, but even I can see the total value when I print in the function, I can't return the value to the main function. Can you tell me where do I do wrong? Thanks for help!
note : more explanation about what I ve been trying to build is : user defines an object and as long as user doesn't give the price, I keep asking what the object is..
small example :
Define the object:
Car
What is Car?:
4*Wheel+1*Frame
What is Wheel?:
2*Rim
What is Rim?
5.0
What is Frame?:
10.0
Total is : 50.0
Current code:
#include <stdio.h>
#include <stdlib.h>
#define INPUT_SIZE 101
void delete_space(char arr[])
{
int a, i, j, len;
for(a = 0; a < INPUT_SIZE; a++)
{
for(i = 0; i < INPUT_SIZE; i++)
{
if(arr[i] == ' ')
{
for(j = i; j < INPUT_SIZE; j++)
{
arr[j] = arr[j + 1];
}
}
}
}
}
double result(char input[], double coeff, double total)
{
/* if the input is number, num_of_obj is 0, if the input is object, num_or_obj is more than 0.
*/
int i, k = 1, num_of_obj = 0;
char temp_input[INPUT_SIZE];
char temp_input_1[INPUT_SIZE];
char x;
int* p;
double value;
p = (int*)calloc(1, sizeof(int));
p[0] = 0;
printf("What is %s:?\n", input);
scanf("%[^\n]s", temp_input);
getchar();
delete_space(temp_input);
for(i = 0; i < INPUT_SIZE; i++)
{
if(temp_input[i] == '*')
{
num_of_obj++;
}
}
if(num_of_obj == 0) // if the input is number.
{
sscanf(temp_input, "%lf", &value);
total = total + coeff * value;
printf("total : %lf", total);
return total;
}
if(num_of_obj > 0)
{
for(i = 0; i < INPUT_SIZE; i++)
{
if(temp_input[i] == '+')
{
p = (int*)realloc(p, (k + 1) * sizeof(int));
p[k] = i + 1;
k++;
}
}
for(i = 0; i < k; i++)
{
sscanf(&temp_input[p[i]], "%lf%c%[^+]s", &coeff, &x, temp_input_1);
result(temp_input_1, coeff, total);
}
}
printf("test");
return total;
}
int main()
{
double total = 0;
char input[INPUT_SIZE];
printf("Define the object :\n");
scanf("%[^\n]s", input);
getchar();
delete_space(input);
printf("total : %.2lf", result(input, 0, 0));
return 0;
}
I believe that the main issue is the recursive call: result(temp_input_1, coeff, total);, which is ignoring the returned result.
Two possible solutions: (1) do the aggregation in result OR (2) tail recursion. I'm not sure that this case fit into tail recursion (or that there are any benefits here). Consider removing the 'total' from result prototype, and doing the aggregation (over the 'components') in the loop.
double result(char input[], double coeff) {
double total ;
...
for(i = 0; i < k; i++)
{
sscanf(&temp_input[p[i]], "%lf%c%[^+]s", &coeff, &x, temp_input_1);
total += result(temp_input_1, coeff, total);
}
Side comment: Consider also removing the 'delete_space' function. I believe it does not property fix the string. Much easier to skip over the spaces in the scanf call.
Welcome to stackoverflow! I too am new here, but if you word your questions right, you'll get better answers. If this is a homework assignment, I highly recommend including that, it can be hard to follow descriptions.
So as a general rule of thumb, when writing C functions its best to use as few return statements as possible. But I too have difficulty with this.
It looks like your are checking for
is first condition met?
if not check next condition
should you be using if, if else, and else?
Also you have if statements with no else, generally needed, especially in a recursive function (you might be skipping over the next step after the last recursive call)
Hope this helps! Swamped with the end of the semester myself or else I would have attempted a solution!
You need three things to write a recursive method successfully:
A terminating condition, so that the method doesn't call itself forever,
Some work to do, and
A recursive call.
Consider the following code:
typedef struct node{
void* item;
struct node* next;
} Node;
int CountNodes(Node* list)
{
if (list == null) return 0;
return 1 + CountNodes(list.next);
}
This code works because it counts the current node plus all remaining nodes. The recursive call counts the next node and all remaining nodes. And so on.
I'm getting a "Segmentation fault" error when i run this!
I'm trying to use the hilbert() function array output as input to another function called determinant(). I tried using static, dynamic array and much more. Here's my code:
(I have to create a hilbert matrix and use that matrix as an input in determinant function to find its determinant)
I am trying to find a 4 by 4 hilbert matrix and then run it by determinant function which contains another deter() function for 3 X 3 matrix.
please help.
#include<stdio.h>
#include<stdlib.h>
double arr3[4][4];
double deter(double m[3][3])
{
double determinant= m[0][0] * ((m[1][1]*m[2][2]) - (m[2][1]*m[1][2])) -m[0][1] * (m[1][0]
* m[2][2] - m[2][0] * m[1][2]) + m[0][2] * (m[1][0] * m[2][1] - m[2][0] * m[1][1]);
return determinant;
}
double determinant(double **a,int o) // o denotes order of the matrix
{
int i,j;
double b[3][3];
int m,n;
int c,s=1; // s is for the signed values; c is used for expanding along the row
double det;
det=0;
for(c=0;c<=o-1;c++) // c used for iterating along the row
{
m=0,n=0;
for(i=0;i<o;i++)
{
for(j=0;j<o;j++)
{
b[i][j]=0; // array b initialized zero
if(i!=0 && j!=c) // For obtaining the matrix of minor by deleting the first row and the concerned element column
{
b[m][n]=a[i][j];
if(n<(o-2)) //to allow elements of the minor to be stored, we need to increment m and n as well.
n++;
else
{
n=0; // restarting the n values for columns
m++; // increment m for next row values
}
}
}
}
det=det+ s * (a[0][c]*deter(b)); // The main recursive determinant function; a[0][c] denotes the expanding along the row approach; next recursion to find determinant of the lesser order minor
s=-1*s; // to get cofactor from minor
}
return(det);
}
double **hilbert()
{
//int m=4;
double **array;
array=malloc(sizeof(int*) * 4);
for(int i = 0 ; i < 4 ; i++)
{ array[i] = malloc( sizeof(int*) * 4);
}
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
array[i][j] = 1.0/((i + 1) + (j + 1) - 1.0);
}
}
/*printf("Hilbert actual is \n");
for(int i=0;i<4;i++)
{
printf("\n");
for(int j=0;j<4;j++)
{
printf("%lf\t",array[i][j]);
}
}
*/
return array;
}
int main()
{
//double a[4][4];
int i,j;
double d;
// hilbert();
// double **ab;
double **aff=hilbert();
/* printf("\nEnter the matrix elements: ");
for(i=0;i<=3;i++)
{
for(j=0;j<=3;j++)
{
scanf("%d",&a[i][j]); //taking the input
}
}
// d=determinant(a,3); //calling the determinant function
//printf("\nDeterminant is %d",d);
*/
printf("\nHilbert matrix is : \n");
for(i=0;i<=3;i++)
{
printf("\n");
for(j=0;j<=3;j++)
{
printf("%lf\t",aff[i][j]); //taking the input
}
}
d=determinant(aff,4); //determinant function
printf("\nDeterminant is %lf",d);
free(aff);
return 0;
}
Your code causes an out-of-bounds write at this line:
array[i][j] = 1.0/((i + 1) + (j + 1) - 1.0);
The following is the runtime error, and here is a live test of your code
=========== Start of #0 stensal runtime message ===========
Runtime error: [out-of-bounds write]
Continuing execution can cause undefined behavior, abort!
-
- Writing 8 bytes to 0x872f050 will corrupt the adjacent data.
-
- The memory-space-to-be-written (start:0x872f040, size:16 bytes) is allocated at
- file:/prog.c::66, 23
-
- 0x872f040 0x872f04f
- +------------------------------+
- |the memory-space-to-be-written|......
- +------------------------------+
- ^~~~~~~~~~
- the write starts at 0x872f050 that is right after the memory end.
-
- Stack trace (most recent call first) of the write.
- [1] file:/prog.c::74, 12
- [2] file:/prog.c::100, 20
- [3] [libc-start-main]
-
============ End of #0 stensal runtime message ============
First of all, a suggested reading:
Correctly allocating multi-dimensional arrays
Then, let's look at hilbert()
double **hilbert()
{
// ...
double **array;
// ^^^^^^
array = malloc(sizeof(int*) * 4); // --> malloc(sizeof *array * 4);
// ^^^^^
for(int i = 0 ; i < 4 ; i++)
{
array[i] = malloc( sizeof(int*) * 4); // --> malloc(sizeof **array * 4)
// ^^^^^^
}
// ...
}
See also the answer by stensal, where an out of bounds access is spotted.
I'm new to C programming so I am probably doing something really stupid here. I am trying to get the value from a 2D array that I read in from a text file ~70m lines.
When running the code, I get a seg fault and I have narrowed it down to line 10: if (i == graph[j][0])
void convertToCSR(int source, int maxNodes, int maxEdges, int* vertices, int* edges, int** graph) {
int i;
int j;
int edge = 0;
for (i = 0; i < maxNodes; i++) {
vertices[i] = edge;
for (j = 0; j < maxEdges; j++) {
if (i == graph[j][0]) {
//Sets edges[0] to the first position
edges[edge] = graph[j][1];
printf("new edge value: %d\n", edge);
edge++;
}
}
}
vertices[maxNodes] = maxEdges;}
I have tried this with smaller datasets e.g 50 bytes and it works fine. With further testing, I print out the value of graph[0][0] and I get a seg fault.
The graph has loaded the data and was allocated like this:
int num_rows = 69000000;
graph = (int**) malloc(sizeof(int*) * num_rows);
for(i=0; i < num_rows; i++){
graph[i] = (int*) malloc(sizeof(int) * 2 );
}
I am also able to get the value of graph[0][0] outside of this method but not inside.What am I doing wrong? I appreciate any help.
EDIT: In my main method, I am doing the following:
readInputFile(file);
int source = graph[0][0];
convertToCSR(source, maxNodes, maxEdges, nodes, edges, graph);
I have the correct value for the variable : source.
It seg faults in the convertToCSR method.
You’re using num_rows to store a number bigger than int capacity.
So the actual value int num_rows is not 69000000, because of the Overflow.
Try to use long unsigned int num_rows instead.