Here is my code.
There is still a mess and some checks missing. But this is not my problem.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define BUF_SIZE 128
typedef struct
{
int gifts_num;
char **Gifts;
}bucket;
int getline(FILE *,char *,int );
int main(int argc, char **argv)
{
int m=20,i,j,addr_num,id,err=0;
int f_id;
char address[BUF_SIZE],ch,l[10];
bucket **buckets,**mem;
FILE *Input;
/////////////////////////////-A Part - /////////////////////
//Allocate memory for bucket array
buckets = malloc(m*sizeof(bucket*));
if(buckets==NULL)
{
fprintf(stderr,"Allocation error.\n");
exit(1);
}
for(i=0;i<m;i++)
{
buckets[i] = malloc(sizeof(bucket));
if(buckets[i]==NULL)
{
fprintf(stderr,"Allocation error.\n");
exit(1);
}
}
//Open input file
Input = fopen("prj3.txt","rb");
if(Input==NULL)
{
fprintf(stderr,"Cannot open : %s\n","prj3.txt");
exit(1);
}
//Count addresses
addr_num=0;
while(ch!=EOF)
{
ch=getc(Input);
if(ch=='\n')
addr_num++;
}
//Allocate memory for bucket addresses
for(i=0;i<m;i++)
{
buckets[i]->gifts_num=0;
buckets[i]->Gifts = malloc(addr_num*sizeof(char *));
if(buckets[i]->Gifts==NULL)
{
fprintf(stderr,"Allocation error.\n");
exit(1);
}
for(j=0;j<addr_num;j++)
{
buckets[i]->Gifts[j] = malloc(BUF_SIZE*sizeof(char));
if(buckets[i]->Gifts[j]==NULL)
{
fprintf(stderr,"Allocation error.\n");
exit(1);
}
}
}
//Get back to the start of the file
fseek(Input,0,SEEK_SET);
//Set seed of rand
srand((unsigned int)time(NULL));
//Read file and store it to buckets
for(i=0;i<addr_num;i++)
{
//Get line as string
getline(Input,address,BUF_SIZE);
//Choose a random bucket
j=(rand() % ((m-1) - 0 + 1) + 0);
//Copy address to bucket and increase bucket's gifts num
strcpy(buckets[j]->Gifts[(buckets[j]->gifts_num)],address);
(buckets[j]->gifts_num)++;
}
//Close input file
fclose(Input);
////////////////////////////-B Part - ////////////////////////////////
// Make shared memroy segment
id = shmget(IPC_PRIVATE,sizeof(bucket **),0666); //Wrong ???
if (id == -1)
perror ("Creation");
// Attach the segment
mem = shmat(id, (void*)0, 0);
if ( (int)mem == -1)
perror("Attachment.");
mem = buckets;//Here is the hot part
memcpy(); // ?????
//Call here children processes by fork
// Remove segment
err = shmctl(id, IPC_RMID, 0);
if (err == -1)
perror ("Removal.");
/////////////////////////////-C Part - /////////////////////////
//Free buckets and their contents
for(i=0;i<m;i++)
{
for(j=0;j<addr_num;j++)
free(buckets[i]->Gifts[j]);
free(buckets[i]->Gifts);
free(buckets[i]);
}
free(buckets);
return 0;
}
In the A Part i make an array of bucket structs, each of it has an array of strings.
In the B Part (in which i have the problem) i want to allocate memory for a share segment in order children processes can access. But the problem is that i can't allocate the real size of all buckets.
I read that share segments are fixed and i can't increase/decrease their size that's why i decided to make an array of buckets and then to copy it to Share Segment using memcpy, but at hot part of my code is obviously wrong.
How can i make the SS with the appropriate size of all bucket array and their contents?
How can i copy the bucket array to SS ?
Is there a possible way ?
In the C Part i free all those buckets and their content
*Thanks in advance*