I want to multiply 2 2D arrays (C[i][j]=A[i][j]*B[i][j] ) in C using shared memory . I have to calculate each multiplication separate calling compute in child process .
A=lm matrix and B=uv matrix , so i have to make l*v child processes where i call compute with execv/execl . I get an segmentation fault (core dumped)
main :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/stat.h>
int main(int argc,char *argv[])
{
FILE *fp;
int **A;
int **B;
int **C;
int l,m,u,v,size;
int pid;
int segment_id;
int *shared_memory;
int i,j,tmp;
//---------------------------------------------
//Reading arrays
fp=fopen("/home/ubuntu-gnome/Desktop/arrays.txt","r");
fscanf(fp,"%d %d",&l,&m);
*A=(int *)malloc(l*sizeof(int));
for(i=1;i<=l;i++){
A[i]=(int *)malloc(m*sizeof(int));
}
for(i=1;i<=l;i++){
for(j=1;j<=m;j++){
fscanf(fp,"%d ",&tmp);
A[i][j]=tmp;
}
}
fscanf(fp,"%d %d",&u,&v);
*B=(int *)malloc(u*sizeof(int));
for(i=1;i<=u;i++){
B[i]=(int *)malloc(v*sizeof(int));
}
for(i=1;i<=u;i++){
for(j=1;j<=v;j++){
fscanf(fp,"%d",&tmp);
B[i][j]=tmp;
}
}
fclose(fp);
//------------------------------------------------------------------
//printing arrays
for(i=1;i<=l;i++){
for(j=1;j<=m;j++){
printf("%d ",A[i][j]);
}
printf("\n");
}
printf("\n*3");
for(i=1;i<=u;i++){
for(j=1;j<=v;j++){
printf("%d" ,B[i][j]);
}
printf("\n");
}
//---------------------------------------------------------------
//Shared Memory
size=sizeof(int)*l*m*u*v*l*v;
segment_id = shmget(IPC_PRIVATE,size,S_IRUSR|S_IWUSR);
shared_memory=(int *)shmat(segment_id,NULL,0);
for(i=1;i<=l;i++)
for(j=1;j<=m;j++)
shared_memory[i*j+j]=A[i][j];
for(i=(l+1);i<=(u+l);i++)
for(j=(1+m);j<=(v+m);j++)
shared_memory[i*j+j]=B[i][j];
//-------------------------------------------------------------------
// Multiplication error beacuse column of A!= row of B
if (u!=m){
printf("\nMultiplication error !\n");
exit(1);
}
//------------------------------------------------------------------
for (i=1;i<=l;i++){
for (j=1;j<=v;j++){
pid=fork();
if(pid>=0){//fork was successful
if (pid==0){//child proccess
execl("/home/ubuntu-gnome/Desktop/compute","compute", (char)segment_id,(char)size,(char)i,(char)j,(char)m,(char)l,(char)v,NULL);
}
else //parent proccess
wait(0);
}
else // fork failed
{
printf("\n Fork failed, quitting!!!!!!\n");
return 1;
}
}
}
//-------------------------------------------------
//filing C
*C=(int *)malloc(l*sizeof(int));
for(i=1;i<=l;i++){
C[i]=(int *)malloc(v*sizeof(int));
}
for(i=1;i<=l;i++){
for(j=1;j<=v;j++){
B[i][j]=shared_memory[m*(l*v)+i];
}
}
//-------------------------------------------------
//printing C=A*B
for(i=1;i<=l;i++){
for(j=1;j<=v;j++){
printf("%d ",C[i][j]);
}
printf("\n");
}
/* now detach the shared memory segment */
shmdt(shared_memory);
/* now remove the shared memory segment */
shmctl(segment_id, IPC_RMID, NULL);
return 0;
}
compute:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/stat.h>
int main(int argc,char *argv[])
{
int segment_id;
int *shared_memory;
int key =atoi(argv[0]);
int size =atoi(argv[1]);
int row=atoi(argv[2]);
int col=atoi(argv[3]);
int m=atoi(argv[4]);
int l=atoi(argv[5]);
int v=atoi(argv[6]);
int i,j,Mul;
shared_memory=(int *)shmat(segment_id,NULL,0);
for (i=row;i<=m;i++){
for (j=col;j<=m;j++){
Mul=Mul+shared_memory[i]*shared_memory[l*m+j];
}
shared_memory[m*(l*v)+i]=Mul;
Mul=0;
}
return 0;
}
arrays.txt :
6 2
2 4
4 8
1 0
3 12
7 2
8 9
2 4
2 4 3 12
6 7 8 5
AFAIK, It should be like that,
int **A = (int **)malloc(l * sizeof(int *));
for (i=0; i<l; i++)
A[i] = (int *)malloc(m * sizeof(int));
Also, you should start arrays from 0. (Why?)
for(i=0;i<l;i++){
for(j=0;j<m;j++){
fscanf(fp,"%d ",&tmp);
A[i][j]=tmp;
}
}
Related
How can I call this convert function using command line and from argument 2 onwards start converting the strings to int and store in an array?
#include <stdio.h>
int main (int argc , char* argv[])
{
int i;
if (argc < 2)
{
printf("Error: Less than two arguments\n");
}
else
{
for(i=0; i<argc; i++)
{
printf("[%d] : %s\n", i , argv[i]);
}
}
return 0;
}
Function in the same directory but in a separate C file:
void convert ( char* parray[] ,int array[] )
{
int i;
printf("The converted array = ");
for (i=0; i< LENGTH; i++)
{
array[i] = atoi(parray[i]);
printf(" %d" , array[i]);
}
printf("\n");
}
You can compile both files into the same executable, e.g like:
gcc -o main main.c convert.c
To use the function in convert.c in main.c, you will have to declare the function before you define the main() function, like this:
#include<stdio.h>
void convert ( char* parray[] ,int array[] );
int main (int argc , char* argv[])
{
// your code ..
//you may now use the convert function inside the main function
convert(param1, param2);
}
Alternatively, you could create a header file for convert.c, called convert.h, like this:
#ifndef CONVERT_H
#define CONVERT_H
void convert ( char* parray[] ,int array[] );
#endif
Then, you could include the headerfile in the main file like this:
#include<stdio.h>
#include "convert.h"
int main (int argc , char* argv[])
{
// use convert here somewhere
convert(param1, param2);
}
Create a module, have the declarations in a separate file, and the implementations in a separate.
functions.h:
#ifndef FUNCTIONS_H /* include guard */
#define FUNCTIONS_H
void convert(char *parray[], int array[], int length);
#endif
functions.c:
#include "functions.h" /* include your header with the declarations */
#include <stdio.h>
#include <stdlib.h>
void convert(char *parray[], int array[], int length)
{
int i;
printf("The converted array = ");
for (i = 0; i < length; i++)
{
array[i] = atoi(parray[i]);
printf(" %d", array[i]);
}
printf("\n");
return;
}
main.c:
#include "functions.h"
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int i, *arr = NULL;
if (argc < 2)
{
printf("Error: Less than two arguments\n");
}
else
{
arr = malloc((argc - 1) * sizeof(int)); /* array can be static too */
if (arr == NULL)
{
exit(EXIT_FAILURE);
/* handle error */
}
convert(&argv[1], arr, argc - 1);
free(arr); /* free when you exit */
}
return 0;
}
Compilation:
clang -c functions.c && clang main.c functions.o
OR
clang functions.c main.c
Output:
$ ./a.out 15 20 -90 18 20 20 8 8 8 81
$ The converted array = 15 20 -90 18 20 20 8 8 8 81
i wrote a programe to read integers from a .txt file and put them in an array, it compiles just fine ,but would ask for the number of integers then stops
#include <stdlib.h>
#include <stdio.h>
void genererN ( int n){
int i=0;
FILE* fichier = NULL;
fichier=fopen("valeurs.txt","w");
while (i<n){
fprintf(fichier,"\n%d\n",rand());
i++;
}
}
void replirtab (int **t,int n){
int i=0;int m;
FILE* fichier = NULL;
fichier=fopen("valeurs.txt","r");
char stre[999999] = "";
while(i<n){
fgets(stre, 999999, fichier);
m = atoi(stre);
*t[i]=m;
i++;
}
}
void affichertab (int *t,int n){
int i=0;
while(i<n){
printf("%d\n",t[i]);
i++;
}
}
and this is my main function where i ask for the number of randomly generated integers and use my functions
#include <stdio.h>
#include <stdlib.h>
#include "source1.h"
int main()
{
int n;
printf("donner le nombre de valeurs ");
scanf("%d",&n);
int T[n];
genererN(n);
replirtab(T,n);
affichertab(T,n);
return 0;
}
and the header
#ifndef SOURCE1_H_INCLUDED
#define SOURCE1_H_INCLUDED
void genererN ( int n);
void replirtab (int *t,int n);
void affichertab (int *t,int n);
#endif // SOURCE1_H_INCLUDED
Fix the following problems:
You're not closing the file after you write it, so the buffer isn't being flushed.
You're writing an extra newline before each number, but you don't skip it when reading.
replirtab() expects an array of pointers, but the array contains integers, not pointers. There's no need to indirect through the references. When you pass an array to a function, a pointer to the first element is passed.
#include <stdlib.h>
#include <stdio.h>
void genererN ( int n){
int i=0;
FILE* fichier = NULL;
fichier=fopen("valeurs.txt","w");
if (!fichier) {
printf("Unable to write file\n");
exit(1);
}
while (i<n){
fprintf(fichier,"%d\n",rand());
i++;
}
fclose(fichier);
}
void replirtab (int *t,int n){
int i=0;int m;
FILE* fichier = NULL;
fichier=fopen("valeurs.txt","r");
if (!fichier) {
printf("Unable to read file\n");
exit(1);
}
char stre[999999] = "";
while(i<n){
fgets(stre, 999999, fichier);
m = atoi(stre);
t[i]=m;
i++;
}
fclose(fichier);
}
void affichertab (int *t,int n){
int i=0;
while(i<n){
printf("%d\n",t[i]);
i++;
}
}
I am trying to make multithread array sorting program in c. But when I run the program, I get an "segmentation fault" error.
Can someone help?
What should I change? First array should be 300 the other should be 500. We sort sequences separately first. After that merge 2 sorted sequences. I use "gcc -pthreads -0 soru1 soru1.c" and "./soru1" commands.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
#define size 800
int orginal_dizi[size], dizi1[300], dizi2[500], dizi3[size];
int sayi,a=1;
int boyutbul(int *the)
{
int number=-1;
while(the[++number]!='\0'){}
return number;
}
void*runner(void *param)
{
int temp,i,k;
int *bolum = param;
sayi = boyutbul(bolum);
printf("\n----------unsorted %d. array-----------\n\n",a);
for(i=0; i<sayi;i++)
printf("%d\n", bolum[i]);
for(i=0; i<sayi;i++)
{
for(k=0; k<(sayi-i-1);k++)
{
if(bolum[k]>bolum[k+1])
{
temp=bolum[k];
bolum[k]=bolum[k+1];
bolum[k+1]=temp;
}
}
}
printf("\n----------sorted %d. array-----------\n\n",a);
for(i=0; i<sayi;i++)
printf("%d\n", bolum[i]);
a++;
pthread_exit(0);
}
int main()
{
pthread_t tid1,tid2, tid3;
int i=0;
while(i<size)
{
int yenisayi=1+rand()%1500;
int aynimi=0, j=0;
while(j<i)
{
if(orginal_dizi[j]==yenisayi)
{
aynimi=1;
break;
}
j++;
}
if(aynimi)
continue;
orginal_dizi[i]=yenisayi;
i++;
}
for(i=0;i<size;i++)
{
if(i<(300))
{
dizi1[i]=orginal_dizi[i];
}
else
{
dizi2[i-(500)-1]= orginal_dizi[i];
}
}
pthread_create(&tid1,NULL,runner,(void *)dizi1);
pthread_join(tid1,NULL);
pthread_create(&tid2,NULL,runner,(void *)dizi2);
pthread_join(tid2,NULL);
for(i=0; i<size;i++)
{
if(i<300)
{
dizi3[i]=dizi1[i];
}
else
{
dizi3[i]=dizi2[i-500];
}
}
pthread_create(&tid3,NULL,runner,(void *)dizi3);
pthread_join(tid3,NULL);
FILE *fp;
if((fp=fopen("son.txt","w"))== NULL)
printf("Dosya acilamadi.");
for(i=0;i<size;i++)
{
fprintf(fp, "%d\n", dizi3[i]);
}
fclose(fp);
return 0;
}
There is no multithreading in this program: every thread is immediately joined; noting runs in parallel.
The real problem is in boyutbul, which tries to figure out the length of the array by looking for '\0'. The way you initialize the arrays, there is no guarantee that they would have the terminating 0 (in fact, they wouldn't have any zeroes), so the program is doomed to access them beyond the bounds. This is UB.
This function is a part of program which will gain statistics about books (amount of specific letters, words etc.). Thing is that segmentation fault appears when trying to malloc:
*wordArray[arrayIndex] = malloc(sizeof(***wordArray)*(wcslen(newWord)+1));
after reallocing whole array
*wordArray = realloc(*wordArray, (arrayIndex+1)*sizeof(**wordArray));
I know that realloc isn't really efficent but the most important thing at the moment is to understand why it doesn't work at all. Thanks a lot.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <wctype.h>
#include <wchar.h>
#define X 2
void wordManager(wchar_t ***, int **, wchar_t *);
int main(int argc, char **argv){
setlocale(LC_ALL, "");
wchar_t **wordArray;
int *wordAmount;
wchar_t word[50];
for(int i=0; i<X; i++){
scanf("%ls", word);
wordManager(&wordArray, &wordAmount, word);
}
for(int i=0; i<X; i++){
printf("%ls; %d times\n", wordArray[i], wordAmount[i]);
}
}
void wordManager(wchar_t ***wordArray, int **wordAmount, wchar_t *newWord){
static int isArrayInitialised = 0;
static int isArrayEmpty = 1;
static int arrayIndex = 0;
int wordLocation;
if(!isArrayInitialised){
*wordArray = malloc(sizeof(**wordArray)*1);
if(*wordArray==NULL){
printf("Error mallocing wordArray");
exit(EXIT_FAILURE);
}
*wordAmount = calloc(1, sizeof(*wordAmount));
if(*wordAmount==NULL){
printf("Error callocing wordAmount");
exit(EXIT_FAILURE);
}
isArrayInitialised = 1;
}
if(isArrayEmpty){
*wordArray[0] = malloc(sizeof(***wordArray)*(wcslen(newWord)+1));
wcscpy(*wordArray[0], newWord);
*wordAmount[0] = 1;
isArrayEmpty = 0;
}
else{
//Check if word is already in an array.
wordLocation = 0;
for(; wordLocation<arrayIndex+1; wordLocation++){
if(!wcscmp(*wordArray[wordLocation], newWord)) break;
}
printf("%d\n", wordLocation);
//Word hasn't been found. Then:
if(wordLocation==arrayIndex+1){
arrayIndex++; //Increase arrays' volume.
*wordArray = realloc(*wordArray, (arrayIndex+1)*sizeof(**wordArray));
if(*wordArray==NULL){
printf("Error reallocating wordArray memory.\n Array index: %d", arrayIndex);
exit(EXIT_FAILURE);
}
*wordAmount = realloc(*wordAmount, (arrayIndex+1)*sizeof(**wordAmount));
if(*wordAmount==NULL){
printf("Error reallocating wordAmount memory.\n Array index: %d", arrayIndex);
exit(EXIT_FAILURE);
}
*wordArray[arrayIndex] = malloc(sizeof(***wordArray)*(wcslen(newWord)+1));
wcscpy(*wordArray[arrayIndex], newWord);
*wordAmount[arrayIndex] = 1;
}
//Word has been found in an array.
else{
(*wordAmount[wordLocation])++;
}
}
}
I am trying to use the getStats function twice - once for each input file. I am supposed to be using a char array called statFile[]to pass as the argument to the prototype to select which file it is to work with. Currently I know how to use one file at a time (by explicit naming the file in the prototype) to make it work, but do not understand how to use it for both inputs. Thanks in advance!
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define AUBURN "auburn2013.txt" //input data files
#define ALABAMA "alabama2013.txt" //input data files
#define NUMGAMES 13
int getStats( char statFile[], int compPass[], int attPass[], int numYds[], int numTD[] );
void analysis( int compPass[], int attPass[], int numYds[], int numTD[], double aveYds[], double pectCmp[], int tdPts[], int numGames[]);
int main(void)
{
int compPass[NUMGAMES],
attPass[NUMGAMES],
numYds[NUMGAMES],
numTD[NUMGAMES];
double bamaStats,
auburnStats,
setAuburn,
setBama;
FILE *au = fopen("auburn2013.txt","r");
FILE *al = fopen("alabama2013.txt","r");
if (al == NULL)
printf("Error Opening File\n");
else if (au == NULL)
printf("Error Opening File\n");
bamaStats = getStats(ALABAMA, compPass, attPass, numYds, numTD);
return 0;
}
int getStats( char statFile[], int compPass[], int attPass[], int numYds[], int numTD[] )
{
int i,
p,
k = sizeof(compPass[NUMGAMES]);
FILE *al = fopen("alabama2013.txt","r");
while (fscanf(al ,"%d %d %d %d", &compPass[i], &attPass[i], &numYds[i], &numTD[i]) !=EOF)
{
i++;
}
printf("Number of Games with data: %d\n", i);
for(p=0; p<8 ; p++)
{
printf("%d %d %d %d\n", compPass[p], attPass[p], numYds[p], numTD[p]);
}
return 0;
}
You are already passing in the stat file name, so need to change:
FILE *al = fopen("alabama2013.txt","r");
to
FILE *al = fopen(statFile,"r");
You can do that like this:
#include <stdio.h>
#include <assert.h>
void print_fname(char **farray, int fnum)
{
int i;
assert(farray != NULL);
for (i = 0; i < fnum; ++i) {
assert(farray[i] != NULL);
printf("file name %d: %s\n", i + 1, farray[i]);
}
}
int main()
{
char *farray[] = {"file1", "file2"};
print_fname(farray, 2);
return 0;
}
Hope can help.