segmentation fault during execution of program - c

I have written a program to create 10 threads and run them normally. The Program is running fine but at the end it gives a segmentation fault. What is this fault, what is causing it, and how do I resolve it?
My code is :
#include<stdio.h>
#include<pthread.h>
void *print(void *num);
int main()
{
pthread_t tid[10];
int n,check;
void *exitstatus;
for(n=1;n<=10;n++)
{
check=pthread_create(&tid[n],NULL,print,(void *)&n);
if(check=0)
printf("thread created");
pthread_join(tid[n],&exitstatus);
}
return 0;
}
void *print(void *num)
{
int i,*val=(int *)num;
for(i=0;i<(5);i++)
printf("Hello World!!!(thread %d )\n",*val);
}

You have many flaws:
for(n=1;n<=10;n++) // No, The array starts from 0 and lasts on 9
Try this
for(n=0;n<10;n++)
if(check=0) // No, this will assign 0 to check instead of compare it
Try this
if(check==0)

You are accessing an array beyond its index. It is undefined behavior.
your array t[10] starts at index t[0] and should end at t[9] -
for(n = 0; n < 10; n++) {
//your stuff
}
Also check == 0 is how you check equality. check = 0 will assign 0 to check
So your code must look like this:
#include<stdio.h>
#include<pthread.h>
void *print(void *num);
int main()
{
pthread_t tid[10];
int n,check;
void *exitstatus;
for(n = 0; n < 10; n++)
{
check=pthread_create(&tid[n], NULL, print, (void *)&n);
if(check == 0)
printf("thread created");
pthread_join(tid[n], &exitstatus);
}
return 0;
}
void *print(void *num)
{
int i,*val=(int *)num;
for(i = 0; i < 5; i++)
printf("Hello World!!!(thread %d )\n", *val);
}
Another important note on programming style: Please use proper indentation and use whitespace judiciously. Most programming errors and bugs can be eliminated if proper indentation and whitespace is used. For example, one white space before and after an operator in the for loop, and between parameters while calling a function after , and before the next parameter.

Related

Function to count the sum of an array

Right, this is (the last) assignment for my C introduction web class.
The assignment presents the main program, does not explain anything about it and tells you to write a function to print and sum the array in it.
However I don't really understand what is going on in the main program.
Translated for your convenience;
Source code:
#include <stdio.h>
#include <stlib.h>
void print_count(int *, int);
int main(int argc, char *argv[]) {
int x, sum = 0, size = 0, array[5];
if (argc == 6) {
/* Program name and parameters received from command line */
for (x = 0; x < argc - 1; x++) {
array[x] = atoi(argv[x + 1]);
}
print_count(array, size);
} else {
printf("Error\n");
}
return 0;
}
Now I am completely clueless as to how to start writing the program requested and what variables to call/how to write the function.
Edit3: completed exercise
void print_count(int *array, int size) {
int i;
int sum = 0;
printf("Elements: ");
for (i = 0; i <= size; i++) {
printf("%d ", (array[i]);
sum = sum += array[i]);
}
printf("\nSum = %d ", sum);
return 0;
}
I would like to understand what is going on in the main program and preferably come to an answer on how to actually write the function by myself.
This:
array[5] = atoi(argv[x+1]);
is clearly wrong, it always tries to assign to array[5] which is out of bounds. It should be:
array[x] = atoi(argv[x + 1]);
This converts the x + 1:th argument from string format into an integer, and stores that in array[x]. If you're not familiar with the standard function atoi(), just read the manual page.
So if you start the program like this:
./myprogram 1 2 3 4 5
That has 6 arguments (the first is the name itself), and will end up with array containing the numbers one through five.
Then in the summing function, the first line should be something like:
void print_count(int *array, int size)
so that you give names to the arguments, which makes them usable in the function. Not providing names is an error, I think.
And it doesn't need to "interact" with main() more than it already does; main() calls print_count(), passing it a pointer to the first element of array and the length of the array, that's all that's needed to compute the sum.
Your print_count function has a few issues:
The loop runs one step too far: i should vary between 0 and size-1 included. The standard idiom for this loop is:
for (i = 0; i < size; i++) {
...
Incrementing sum is simply done with:
sum += array[i];
There is an extra ( on the first printf line.
You should print a newline after the output.
Returning 0 from a void function is invalid.
Here is a corrected version:
void print_count(int *array, int size) {
int i;
int sum = 0;
printf("Elements: ");
for (i = 0; i < size; i++) {
printf("%d ", array[i]);
sum += array[i]);
}
printf("\nSum = %d\n", sum);
}
the following proposed code:
cleanly compiles.
explains what is being accomplished at each step of the 'main()' function.
properly outputs error messages to 'stderr'.
implements the typical method to announce an error in the number of command line parameters.
Now the proposed code with explanatory comments:
#include <stdio.h> // printf(), fprintf()
#include <stdlib.h> // atoi(), exit(), EXIT_FAILURE
void print_count(int *, int);
int main(int argc, char *argv[])
{
if (argc != 6)
{
fprintf( stderr, "USAGE: %s int1 int2 int3 int4 int5\n", argv[0] );
exit( EXIT_FAILURE );
}
// implied else, correct number of arguments
// only declare variables when they are needed
int array[5];
// place each command line parameter into 'array',
// except program name
// I.E. skip the program name in argv[0]
for( int i = 1; i < argc; i++ )
{
// array[] index starts at 0, but loop counter starts at 1
array[i-1] = atoi(argv[i]);
} // end for( each value pointed at by argv[], except program name )
// print sum of command line parameters to stdout
int size = argc-1; // number of command line parameters after program name
print_count(array, size);
return 0;
} // end function: main

How to remove the Segmentation Fault in this code

I am writing the code to solve the Rod Cut problem but I have been getting Segmentation Fault prompts at run-time. I tried to debug this using gdb and it showed the issue with the recRodCut function. Can anyone please help me find the issue?
#include <stdio.h>
int recRodCut(int* arr, int n)
{
int res;
int i;
if(n==0)
{
return 0;
}
for( i = 0; i< n ; i++)
{
res = max(recRodCut(arr,n) , arr[i]+recRodCut(arr,n-i));
}
return res;
}
int max(int a, int b)
{
return (a<b)?a:b;
}
int main()
{
int value[] = {0,1,5,8,9,10,17,17,20,24,30};
int result = recRodCut(value, 4);
printf("The value is %d \n", result);
}
I'm not seeing a segfault here, but I am seeing an unterminated recursion, which ends up in a stack overflow.
Consider how you are calling your recRodCut():
recRodCut(value, 4);
// i = 0, first iteration:
res = max(recRodCut(value, 4), value[0]+recRodCut(value, 4-0));
As you can see, you are always calling recRodCut with the same arguments. Which means it will never hit if(n==0) and bail early.
By the way, your max() function is actually a min() function :)

Unexpected results from passing int-value in multithreading, C

I am currently trying to learn about multi-threading in C. But I have got very unexpected results which have left me stumped. In this program, I am trying to fill up a matrix by using threads. I am creating 1024 threads, passing the i value into the function. Then I proceed to use it.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define SIZE 1024
static double a[SIZE][SIZE];
static double b[SIZE][SIZE];
static double c[SIZE][SIZE];
void*
init_matrix(void* msg)
{
int j;
int num = *((int*) msg);
printf("%d\n", num);
for (j = 0; j < SIZE; j++) {
a[num][j] = drand48();
b[num][j] = drand48();
}
pthread_exit(NULL);
}
int
main(int argc, char **argv)
{
//Init threads
pthread_t p_initThreads[SIZE];
int i,j;
for(i = 0; i< SIZE; i++)
{
pthread_create(&p_initThreads[i], NULL, init_matrix, (void*)&i);
}
for(j = 0; j<SIZE; j++)
{
pthread_join(p_initThreads[j], NULL);
}
}
Expected results from the prinf would be; 1-2-3-4-5-6-7-8-9-10. With the possible
result of it being inorder due to of it being in threads. But the reults on my computer is this;
1-2-2-4-5-7-24-25-25-25-25-25-25-25-25-25-25-25-25-25-25-25-25-25-25-26-35-36-36-37-37-37-37-37-37-37-37-38-39-40
By commentating out;
for (j = 0; j < SIZE; j++) {
a[num][j] = drand48();
b[num][j] = drand48();
}
I get the result that I want. Why is that? It should not do anything to num!
You are passing the address of i as the input parameter of the thread. If you were passing the value of i, you would get 1-2-3-4-5-... . But when you pass the address, it is entirely possible that before the printf line is executed, the main thread already incremented i. And printf displays the current value of i, not the value it had at the moment of thread creation.
What you have is a race condition with multiple threads accessing the same memory location (variable i) since you are passing the address of i to all threads.
What you really wanted to do was pass the value of i. Call the pthread_create() with:
pthread_create(&p_initThreads[i], NULL, init_matrix, (void*)i);
and read the value as:
int num = (int) msg;
instead of : int num = *((int*) msg);
You should also check if pthread_create() returns non-zero for failures. If that's the case, you are not going to get expected results.

accessing values in a struct array

I am passing in an array into a function straightflush. I use a counting loop so i can get to all of the elements but for some reason, even tho the counter i increases, i get the value and suit for the first element of the array. Therefore, only my spadesCount increases as it always shows 4 for the value and spade for the suit.
struct card{
int value;
char suit;
};
int straightflush(struct card hand[], int n)
{
int clubsCount = 0;
int diamondsCount = 0;
int heartCount = 0;
int spadesCount =0;
int i;
for(i=0; i<n; i++)
{
if (hand[i].suit == 'c')
{
clubsCount++;
}
else if (hand[i].suit == 'd')
{
diamondsCount++;
}
else if (hand[i].suit == 'h')
{
heartCount++;
}
else{
spadesCount++;
}
}
return 0;
}
here is my main:
int main(){
struct card hand1[] = {{4,'s'}, {9,'s'},{12,'c'},{11,'s'},{8,'s'},
{6,'d'}, {3,'d'},{7,'s'},{10,'s'},{12,'d'}};
printf ("%d\n", straightflush(hand1, 10));
}
I just run your code and the four count variables have correct values. I think it's because you are returning 0 at the end of your straightflush function, the output is always 0.
You can use a debugger or add the following line before the return statement in straightflush() to prove that your counts are actually accurate.
printf("%d %d %d %d\n", clubsCount, diamondsCount, heartCount, spadesCount);
Your return value has nothing to do with the values you read thus the printf statement in your main() function is not printing the count of any thing, it is just printing 0 no matter what.
If you want the counts accessible outside of striaghtflush() you need to either use global variables for those counts (a generally shunned idea) or pass some values in by reference. An example of this would be:
#include <stdio.h>
#include <stdlib.h>
void editValues( int *numDiamonds, int *numClubs, int *numHearts, int *numSpades ){
*numDiamonds = 3;
*numClubs = 5;
*numHearts = 7;
*numSpades = 11;
}
int main(int argc,char**argv)
{
int numD=0, numC=1, numH=2, numS=3;
printf("%d %d %d %d\n", numD, numC, numH, numS);
editValues(&numD, &numC, &numH, &numS);
printf("%d %d %d %d\n", numD, numC, numH, numS);
return 0;
}

How can I initiate an array, each element in a separate thread

I am trying to create an array of size n (where n is user's input) and when the user runs the program, the array elements should be set to 1 (each in a separate thread). Here is what I have done so far:
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <process.h>
int *x;
DWORD WINAPI init_X(LPVOID param)
{
int index = *(int *) param;
x[index] = 1;
return 0;
}
int main(int argc, char *argv[])
{
int n = atoi(argv[1]);
int i; // counter.
HANDLE THandles[n];
x = malloc(n * sizeof (int));
for(i = 0; i < n; i++)
{
THandles[i] = CreateThread(NULL, 0, init_X, &i, 0, NULL);
}
// Now wait for threads to finish
WaitForMultipleObjects(n, THandles, TRUE, INFINITE);
// Close the thread handle
for(i = 0; i < n; i++)
{
CloseHandle(THandles[i]);
}
printf("After initialization x = ");
for(i = 0; i < n; i++)
{
printf("%d ", x[i]);
if(i < n - 1) printf(" ");
}
// ...
return 0;
}
I run this program and I got wrong outputs:
> Test.exe 3
After initialization x = 11611536 11600064 50397186
It should be After initialization x = 1 1 1 though. I am not sure how I can I fix this, but I am sure its something related to the pointers.
P.S: I'm Java programmer so I'm not familiar with pointers.
The value you are passing as your array index will more than likely be invalid by the time the thread runs, as there is no guaranteeing that the thread is run immediately after the call to CreateThread.
You have two solutions, either pass by value (simple & easy, but not always safe) or allocate a temporary buffer for the value that will be freed by the thread when its used.
Minor Update:
In fact, a better way would be to pass &x[i], then you can just do *(int*)param = 1;
You are passing i by pointer to the thread, so the value each thread gets will depend on when int index = *(int *) param; actually executes and it should be something between 0 and n. You can just pass i by value (casted to a pointer) to avoid this.

Resources