Getting segmentation fault and varying output when running program - c

I have a program that is supposed to copy the contents of a file exactly to another file using multiple threads. The reader thread reads a line from the file and stores it in a circular buffer. The writer thread then reads from the buffer and writes to the file. However I am getting a segmentation fault and it is not writing to the file. Any idea why I am getting a segmentation fault or is there any way that I can find out what is causing the error?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
FILE *inputFile;
FILE *outputFile;
pthread_mutex_t mutex;
int endOfFile = 0;
typedef struct bufferStruct{
int capacity;
int size;
int head;
int tail;
char **data;
}buffer;
buffer * bufferInit(int maxElements){
buffer *buf;
buf = (buffer *)malloc(sizeof(buffer));
buf->data = (char**)malloc(sizeof(char*)*maxElements);
buf->size = 0;
buf->capacity = maxElements;
buf->head = 0;
buf->tail = -1;
return buf;
}
void popFront(buffer *buf){
if(buf->size != 0){
free(buf->data);
buf->size--;
buf->head++;
if(buf->head == buf->capacity){
buf->head = 0;
}
}
return;
}
char* front(buffer *buf){
if(buf->size != 0){
return buf->data[buf->head];
}
return NULL;
}
void pushBack(buffer *buf, char *data){
if(buf->size == buf->capacity){
printf("Queue is Full\n");
}
else{
buf->size++;
buf->tail = buf->tail + 1;
if(buf->tail == buf->capacity){
buf->tail = 0;
}
buf->data[buf->tail] = (char *) malloc((sizeof data + 1)* sizeof(char));
strcpy(buf->data[buf->tail], data);
}
return;
}
buffer *buf;
void* reader(void* arg){
char line[1024];
while(endOfFile != 1){
fgets(line, sizeof(line), inputFile);
printf("Line read: %s", line);
pushBack(buf, line);
if(feof(inputFile)){
endOfFile = 1;
}
}
pthread_exit(0);
}
void* writer(void* arg){
char *line;
while(endOfFile != 1){
pthread_mutex_lock(&mutex);
line = front(buf);
fputs(line, outputFile);
popFront(buf);
pthread_mutex_unlock(&mutex);
}
pthread_exit(0);
}
int main(int argc, char **argv){
if (argc < 4) {
printf("Usage: %s <input file> <output file> <number>\n", argv[0]);
exit(-1);
}
inputFile = fopen(argv[1], "r");
outputFile = fopen(argv[2], "w");
int numOfThreads = atoi(argv[3]);
buf = bufferInit(16);
pthread_t readerTids[numOfThreads];
pthread_t writerTids[numOfThreads];
pthread_mutex_init(&mutex, NULL);
for(int i = 0; i < numOfThreads; i++){
if(endOfFile != 1){
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&readerTids[i], &attr, reader, NULL);
pthread_create(&writerTids[i], &attr, writer, NULL);
printf("Thread %d created\n", i);
}
}
for (int i = 0; i < numOfThreads; i++) {
pthread_join(readerTids[i], NULL);
pthread_join(writerTids[i], NULL);
}
fclose(inputFile);
fclose(outputFile);
}

Consider the possibility of your reader thread being slower than the writer thread. The writer thread alone holds the lock, does the locking and unlocking, not being bothered about the reader. What if the writer tries to use the buffer when reader hasn't updated the buffer yet? Use thread synchronisation, say semaphores, which does not have any ownership issues.
void* reader(void* arg){
char line[1024];
while(endOfFile != 1){
fgets(line, sizeof(line), inputFile);
printf("Line read: %s", line);
pushBack(buf, line);
--- Lock semaphore here---
if(feof(inputFile)){
endOfFile = 1;
}
}
pthread_exit(0);
}
void* writer(void* arg){
char *line;
while(endOfFile != 1){
-- Unlock semaphore here---
line = front(buf);
fputs(line, outputFile);
popFront(buf);
}
pthread_exit(0);
}
Unlike mutex, the same semaphore can be used between both threads. This helps you to sync up both threads.

Related

Scanf printing weird characters after the input

This code takes in input N-file names and generates N-threads, then the main thread writes something and puts it in a buffer for each thread, and each threads writes their buffer content on their own file. Everything works fine but on the file, the input is like this and i don't know why, hope someone can help me, thanks in advance
Hello����������������������������������������������������������������������������������������������������������������������������
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/mman.h>
#include <semaphore.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define fflush(stdin) while (getchar() != '\n')
int n_threads;
FILE **source_files;
char **files;
char buffers[128][128];
pthread_mutex_t *ready;
pthread_mutex_t *done;
char buff[256];
void *thread_function(void *);
int main(int argc, char **argv) {
long i, j, ret;
pthread_t tid;
if (argc < 2) {
printf("Error: Usage -> prog | file1 ... fileN\n");
exit(1);
}
n_threads = argc - 1;
files = argv + 1;
for(i = 0; i < n_threads; i++) {
for(j = 0; j < n_threads; j++) {
if(strcmp(files[i], files[j]) == 0 && i != j) {
puts("Strings are equal.\n");
exit(1);
}
}
}
puts("Strings are different");
/*buffers = (char **)malloc(sizeof(char *) * n_threads);
if(buffers == NULL) {
printf("Malloc error.\n");
exit(1);
}*/
source_files = (FILE **)malloc(sizeof(FILE *) * n_threads);
if(source_files == NULL) {
printf("Malloc error.\n");
exit(1);
}
ready = malloc(sizeof(pthread_mutex_t));
done = malloc(sizeof(pthread_mutex_t));
if (ready == NULL || done == NULL) {
printf("Malloc error.\n");
exit(1);
}
if(pthread_mutex_init(ready, NULL) || pthread_mutex_init(done, NULL) || pthread_mutex_lock(ready)) {
printf("Mutex init error.\n");
exit(1);
}
for(i = 0; i < n_threads; i++) {
if(pthread_create(&tid, NULL, thread_function, (void *) i)) {
printf("Error while creating thread %ld.\n", i);
exit(1);
}
}
//signal(SIG_INT, printer);
i = 0;
while(1) {
if(pthread_mutex_lock(done)) {
printf("Mutex lock error.\n");
exit(1);
}
ret = scanf(" %s", buff);
if(ret == EOF) {
printf("Scanf error.\n");
exit(1);
}
if (ret == 0) {
printf("Non compliant input.\n");
exit(1);
}
getchar();
puts("before strcpy\n");
strcpy(buffers[i],buff);
puts("after strcpy\n");
if(pthread_mutex_unlock(ready)) {
printf("Mutex unlock error.\n");
exit(1);
}
i=(i+1)%n_threads;
}
}
void *thread_function (void *arg) {
int fd;
//FILE *file;
long me = (long) arg;
printf("Thread %ld started.\n", me);
puts("before opening file.\n");
fd = open(files[me], O_CREAT | O_RDWR | O_TRUNC, 0666);
//file = fdopen(fd, "w+");
puts("after opening file.\n");
while(1) {
if(pthread_mutex_lock(ready)) {
printf("Mutex lock error.\n");
exit(1);
}
printf("Thread %ld took string %s.\n", me, buffers[me]);
puts("before fprintf.\n");
//fprintf(file, "%s", buffers[me]);
write(fd, buffers[me], 128);
puts("after fprintf.\n");
if(pthread_mutex_unlock(done)) {
printf("Mutex unlock error.\n");
exit(1);
}
}
}

Thread function malfunctions, incomplete output and segmentation error

The following code is supposed to create one Producer thread and one Consumer thread. The Producer creates random numbers, adds them to a circular buffer(push_back()) and then writes them in an output txt called prod_out.txt. The Consumer "consumes" these numbers by poping them (pop_front()) and then writing them in an output txt called cons_out.txt. For a call like this ./a.out 1 1 10 20 1 the arguements are as follows: there will be 1 producer, 1 consumer, 10 is circular buffer's capacity, 20 random numbers will be generated and the seed for rand_r is 1.
If the buffer's capacity is smaller than the ammount of random nums to be generated the program only writes 9 numbers in the consumers' txt, while the producers' txt is just fine. If they are the same then the consumers' txt does not get created and producers' txt misses one number (namely the last one, just like the consumer txt does when the capacity is smaller than the numbers generated).
This is the main function
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include "prodcons.h"
FILE * fp;
int rc;
circular_buffer* cb;
int fileW, my_random;
pthread_mutex_t Mutex;
pthread_cond_t Condition;
args* t_args;
void* Producers(void* fargs){
printf("I am Producer and I am not locked\n");
args* f_args= fargs;
rc = pthread_mutex_lock(&Mutex);
printf("I am Producer and I am locked\n");
if (rc != 0) {
printf("ERROR: return code from pthread_mutex_lock() is %d\n", rc);
pthread_exit(&rc);
}
printf(" The ruler of all mutexes has passed from here and shall start
creating random numbers\n");
for(int i=0; i < *(f_args->rand_count); i++){
if(i==cb->capacity){
printf(" Your producer king will now sleep\n");
rc = pthread_cond_signal(&Condition);
if (rc != 0) {
printf("ERROR: return code from pthread_cond_signal() is %d\n",
rc);
pthread_exit(&rc);
}
rc = pthread_cond_wait(&Condition, &Mutex);
if (rc != 0) {
printf("ERROR: return code from pthread_cond_wait() is %d\n",
rc);
pthread_exit(&rc);
}
}
my_random =rand_r(f_args->seed)%255;
printf ( "Creating random number %d.\n", my_random);
cb_push_back(cb, &my_random);
if(i==0){
fp=fopen("prod_in.txt", "w");
}else{
fp=fopen("prod_in.txt", "a");
}
fprintf(fp, "Producer %d: %d\n", f_args->ID, my_random);
fclose(fp);
}
printf("I am going to go to signal the consumer.\n");
rc = pthread_cond_signal(&Condition);
if (rc != 0) {
printf("ERROR: return code from pthread_cond_signal() is %d\n", rc);
pthread_exit(&rc);
}
rc = pthread_mutex_unlock(&Mutex);
if (rc != 0) {
printf("ERROR: return code from pthread_mutex_unlock() is %d\n", rc);
pthread_exit(&rc);
}
}
void* Consumer(void* t1){
int *threadId = (int *) t1;
printf("I am Consumer and I am NOT locked\n");
rc = pthread_mutex_lock(&Mutex);
printf("I am Consumer and I am locked\n");
if (rc != 0) {
printf("ERROR: return code from pthread_mutex_lock() is %d\n", rc);
pthread_exit(&rc);
}
if(cb->count == 0){
rc = pthread_cond_wait(&Condition, &Mutex);
if (rc != 0) {
printf("ERROR: return code from pthread_cond_wait() is %d\n", rc);
pthread_exit(&rc);
}
}
int counter = cb-> count;
for (int j=0; j<= counter; j++){
printf("Consumer will now consume with items remaining %d.\n", (int)cb-
>count);
if(j==0){
fp=fopen("cons_out.txt", "w");
}else{
fp=fopen("cons_out.txt", "a");
}
printf("I will now write the following %d, %d inside the
file.\n",*threadId,my_random);
fprintf(fp, "Consumer %d: %d\n",*threadId, my_random);
cb_pop_front(cb,&my_random);
if(cb->count == 0){
rc = pthread_cond_signal(&Condition);
if (rc != 0) {
printf("ERROR: return code from pthread_cond_signal() is %d\n",
rc);
pthread_exit(&rc);
}
rc = pthread_cond_wait(&Condition, &Mutex);
if (rc != 0) {
printf("ERROR: return code from pthread_cond_wait() is %d\n",
rc);
pthread_exit(&rc);
}
}
fclose(fp);
}
rc = pthread_mutex_unlock(&Mutex);
if (rc != 0) {
printf("ERROR: return code from pthread_mutex_unlock() is %d\n", rc);
pthread_exit(&rc);
}
}
int main(int argc, char *argv[]){
if (argc !=6){
printf("ERROR: the program should take five arguments!\n");
exit(-1);
}
if(atoi(argv[1])!= 1 || atoi(argv[2])!= 1){
printf("ERROR:This program only functions for one producer and
consumer.\n");
exit(-1);
}
int main_seed = atoi(argv[5]);
int main_rand = atoi(argv[4]);
int buffer_size = atoi(argv[3]);
cb=(circular_buffer*) malloc(sizeof(struct circular_buffer));
t_args=(args*)malloc(sizeof(struct args));
cb_init(cb, buffer_size, sizeof(int));
t_args->seed= &main_seed;
t_args->rand_count= &main_rand;
t_args->ID=1;
int t1=1;
pthread_t p1, c1;
printf ( "I am the ruler of all mutexes. I now shall initialise the
mutex\n");
rc = pthread_mutex_init(&Mutex, NULL);
if (rc != 0) {
printf("ERROR: return code from pthread_mutex_init() is %d\n", rc);
exit(-1);
}
rc = pthread_cond_init(&Condition, NULL);
if (rc != 0) {
printf("ERROR: return code from pthread_cond_init() is %d\n", rc);
exit(-1);
}
rc = pthread_create(&p1, NULL, Producers, (void*)t_args); //cast σε void????
if (rc != 0) {
printf("ERROR: return code from pthread_create() is %d\n", rc);
exit(-1);
}
rc = pthread_create(&c1, NULL,Consumer, &t1);
if (rc != 0) {
printf("ERROR: return code from pthread_create() is %d\n", rc);
exit(-1);
}
void *status;
rc = pthread_join(p1, &status);
if (rc != 0) {
printf("ERROR: return code from pthread_join() is %d\n", rc);
exit(-1);
}
printf("Main(): Thread %d terminated successfully.\n", *(int *) status);
rc = pthread_join(c1, &status);
if (rc != 0) {
printf("ERROR: return code from pthread_join() is %d\n", rc);
exit(-1);
}
printf("Main(): Thread %d terminated successfully.\n", *(int *) status);
rc = pthread_mutex_destroy(&Mutex);
if (rc != 0) {
printf("ERROR: return code from pthread_mutex_destroy() is %d\n", rc);
exit(-1);
}
rc = pthread_cond_destroy(&Condition);
if (rc != 0) {
printf("ERROR: return code from pthread_cond_destroy() is %d\n", rc);
exit(-1);
}
free(cb);
free(t_args);
return 1;
}
This is a header file with the 2 structs and the circular buffer functions
#include "stdio.h"
#include "sys/types.h"
#include "stdlib.h"
#include "string.h"
typedef struct circular_buffer
{
void *buffer; // data buffer
void *buffer_end; // end of data buffer
size_t capacity; // maximum number of items in the buffer
size_t count; // number of items in the buffer
size_t sz; // size of each item in the buffer
void *head; // pointer to head
void *tail; // pointer to tail
}circular_buffer;
typedef struct args
{
int ID; //Unique ID from 1 to n
int* seed; //The seed used for rand_r
int* rand_count; //The number of random generated numbers
}args;
void cb_push_back(circular_buffer *cb, const void *item);
void cb_pop_front(circular_buffer *cb, void *item);
void cb_init(circular_buffer *cb, size_t capacity, size_t sz);
void cb_free(circular_buffer *cb);
In this file are the implementetions of the circular buffer functions
#include "prodcons.h"
//initialize circular buffer
//capacity: maximum number of elements in the buffer
//sz: size of each element
void cb_init(circular_buffer *cb, size_t capacity, size_t sz)
{
cb->buffer = malloc(capacity * sz);
if(cb->buffer == NULL){
printf("Could not allocate memory..Exiting! \n");
exit(1);
}
// handle error
cb->buffer_end = (char *)cb->buffer + capacity * sz;
cb->capacity = capacity;
cb->count = 0;
cb->sz = sz;
cb->head = cb->buffer;
cb->tail = cb->buffer;
}
//destroy circular buffer
void cb_free(circular_buffer *cb)
{
free(cb->buffer);
// clear out other fields too, just to be safe
}
//add item to circular buffer
void cb_push_back(circular_buffer *cb, const void *item)
{
if(cb->count == cb->capacity)
{
printf("Access violation. Buffer is full\n");
exit(1);
}
memcpy(cb->head, item, cb->sz);
cb->head = (char*)cb->head + cb->sz;
if(cb->head == cb->buffer_end)
cb->head = cb->buffer;
cb->count++;
}
//remove first item from circular item
void cb_pop_front(circular_buffer *cb, void *item)
{
if(cb->count == 0)
{
printf("Access violation. Buffer is empy\n");
exit(1);
}
memcpy(item, cb->tail, cb->sz);
cb->tail = (char*)cb->tail + cb->sz;
if(cb->tail == cb->buffer_end)
cb->tail = cb->buffer;
cb->count--;
}

Changing unrelated code gives a segmentation fault. Why is it doing this?

I'm creating my own Shell and I successfully got processes to run in the background by using my is_background function to find a &. It was working fine until i tried to implement redirection of standard output. The chk_if_output function is a part of this as well as the if statement if(out[0] == 1) in the process function. Somehow implementing redirection screwed up the way I implemented background process. If I comment out the redirection code it works again. I get a segmentation fault every time I try to run a background process with the redirection code in the program and I can't for the life of me figure out why. I haven't changed any of the background process code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#define MAX_LINE 80 /* The maximum length command */
int is_background(char *args[], int size){
int background = 0;
if (strcmp(args[size-1 ], "&") == 0){
background = 1;
args[size-1] = NULL;
}
return background;
}
int * chk_if_output(char *args[], int size){
int * out = malloc(2);
out[0] = 0; out[1] = 0;
for (int i = 0; i < size; i++){
if (strcmp(args[i],">") == 0){
out[0] = 1;
out[1] = i;
break;
}
}
return out;
}
void process(char *command, char *params[], int size){
pid_t pid;
int background = is_background(params, size);
int *out = chk_if_output(params, size);
int fd;
int fd2;
pid = fork();
if (pid < 0) {
fprintf(stderr, "Fork Failed\n");
}else if (pid == 0) {
if(out[0] == 1){
for (int i = out[1]; i < size; i++){
params[i] = params[i+1];
}
fd = open(params[out[1]-1],O_RDONLY,0);
dup2(fd,STDIN_FILENO);
close(fd);
fd2 = creat(params[out[1]],0644);
dup2(fd2,STDOUT_FILENO);
close(fd2);
out[0] = 0;
out[1] = 0;
}
execvp(command, params);
}else {
if(background == 1){
waitpid(pid, NULL, 0);
}
background = 0;
}
}
int main(void) {
char *args[MAX_LINE/2 + 1]; /* command line arguments */
int should_run = 1; /* flag to determine when to exit program */
while (should_run) {
char *line;
char *endline;
printf("Leyden_osh>");
fgets(line, MAX_LINE*sizeof line, stdin);
if((endline = strchr(line, '\n')) != NULL){
*endline = '\0';
}
if (strcmp((const char *)line,"exit") == 0){
should_run = 0;
}
int i = 0;
args[i] = strtok(line, " ");
do{
args[++i] = strtok(NULL, " ");
}while(args[i] != NULL);
process(args[0], args, i);
fflush(stdout);
return 0;
}
In the chk_if_output() function, the last element of the array in the loop was NULL.
Fixed it by looping to size -1.

Sum of words using threads

Problem: Implement a program that gets as arguments a file name followed by words. For each word, create a separate thread that counts its appearances in the given file.Print out the sum of the appearances of all words.
Below I did a code but I receive : Segmentaion Fault (core dumped) when I run it.
PS: I do not know if the code is correct and does the requirement succesfully
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
pthread_mutex_t mtx;
int sum = 0;
char filename[10];
char word[10];
void * voidCount(void* p){
char cmd[100], appearences[100];
FILE *f;
sprintf(cmd, "echo %s | grep -o %s | wc -l", filename, word);
f = popen(cmd, "r");
fgets(appearences, sizeof(int), f);
pthread_mutex_lock(&mtx);
sum += *((int*)appearences);
pthread_mutex_unlock(&mtx);
return NULL;
}
int main(int argc, char *argv[]){
pthread_mutex_init(&mtx, NULL);
pthread_t threads[argc-1];
int i = 0;
for ( i = 1; i < argc-1; i++){
strcpy(filename, argv[1]);
strcpy(word, argv[i]);
pthread_create(&threads[i], NULL, voidCount, NULL);
}
for (i = 0; i < argc-1; ++i){
pthread_join(threads[i], NULL);
}
printf("Total appearences: %d", sum);
pthread_mutex_destroy(&mtx);
return 0;
}
The program has to complete few tasks in order to solve the problem:
set the number of threads depending on the number of words to search for
properly allocate and initialize thread arguments
pass each individual word as individual thread argument
protect shared variables during computation
get the results
Here's a minimal functional demo rework of your code with few essential comments. Word search is case sensitive.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
pthread_mutex_t mtx;
int sum = 0;
char filename[10]; //declared global for simplicity
//we search all the words in the same file
void * voidCount(void* p){
char *word, cmd[100], appearences[100];
int num;
FILE *f;
word = ((char*)p);
printf ("word : %s\n",word);
sprintf(cmd, "more %s | grep -o %s | wc -l", filename, word);//echo didn't work
printf ("%s\n",cmd); //debug print
pthread_mutex_lock(&mtx);
f = popen(cmd, "r");
if(fgets(appearences, sizeof(appearences), f) == NULL)
printf("Pipe error\n"); //better error handling is welcome...
printf("Appearances of \"%s\": %s\n", word, appearences);
num = atoi(appearances); //convert string to int
sum += num;
pclose(f); //close pipe
pthread_mutex_unlock(&mtx);
return NULL;
}
int main(int argc, char *argv[])
{
pthread_mutex_init(&mtx, NULL);
pthread_t threads[argc-1];
char **data = calloc(argc,sizeof(char*)); // initialize thread data
int i = 0;
strcpy(filename, argv[1]);
for ( i = 2; i < argc; i++){
data[i-2] = calloc(33, sizeof(char));//let's allow for somewhat longer words
strcpy(data[i-2], argv[i]);
strcat(data[i-2], "\0");
pthread_create(&threads[i-2], NULL, voidCount, data[i-2]);//each word a thread arg
}
for (i = 0; i < argc-1; ++i){;
pthread_join(threads[i], NULL);
}
printf("Total appearences: %d\n", sum);
pthread_mutex_destroy(&mtx);
for (i = 0; i < argc; i++)//free thread data
free (data[i]);
free (data);
return 0;
}
Hope this can help.

Segmentation fault when using fork() in C

Basically what i'm trying to do is read a number from a file, increment the value by one, and then write the number back to the same file. Using fork() is supposed to have both processes accessing the file but using locks so they take turns. I keep getting a segmentation fault.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void appendValue(FILE *, int *);
int readValue(FILE *, int *);
void lockFile(FILE *);
void unlockFile(FILE *);
void whatProcess(pid_t *pID);
int main(void) {
pid_t pID;
pID = fork();
int value = 0, counter = 0;
int *valPtr = &value;
pid_t *pidPtr = &pID;
FILE *file = fopen("output.txt", "a+");
lockFile(file);
while(counter < 1000) {
whatProcess(pidPtr);
value = readValue(file, valPtr);
value++;
appendValue(file, valPtr);
rewind(file);
counter++;
}
unlockFile(file);
fclose(file);
printf("\n");
return 0;
}
void whatProcess(pid_t *pID) {
if(*pID > 0) {
printf("\n --- In Parent ---");
} else if(*pID == 0) {
printf("\n --- In Child ---");
} else {
printf("\n --- fork() Failed ---");
}
}
void lockFile(FILE *file) {
int lock;
lock = lockf(fileno(file), F_LOCK, 0);
while(lock != 0) {}
if(lock == 0) {
printf("\nPID %d: Lock Successful", getpid());
} else {
printf("\nPID %d: Lock Unsuccessful", getpid());
}
}
void unlockFile(FILE *file) {
int lock;
lock = lockf(fileno(file), F_LOCK, 0);
while(lock != 0) {}
if(lock == 0) {
printf("\nPID %d: Unlock Successful", getpid());
} else {
printf("\nPID %d: Unlock Unsuccessful", getpid());
}
}
void appendValue(FILE *file, int *value) {
fprintf(file, "%d\n", *value);
}
int readValue(FILE *file, int *value) {
while(!feof(file)) {
fscanf(file, "%d", value);
}
return *value;
}
The fscanf in readValue is writing to a non-allocated location. You are passing value in as a pointer so there is no need to use the address of operator.
int readValue(FILE *file, int *value) {
fscanf(file, "%d", value);
printf("\nreadValue(): %d", *value);
return *value;
}
Or, even better:
int readValue(FILE *file, int *value) {
if (fscanf(file, "%d", value) == 1) {
printf("\nreadValue(): %d", *value);
return 0;
}
return -1;
}
Your current function does not indicate whether it has succeeded or failed. Either add a status return value (zero, -1 are pretty common) or omit error checking and do this instead:
int readValue(FILE *file) {
int buf;
if (fscanf(file, "%d", &buf) == 1) {
printf("\nreadValue(): %d", buf);
} else {
perror("readValue(): fscanf failed");
}
return buf; /* could be a garbage value, use at own risk */
}

Resources