Why do I get a still reachable block after mallocing a char*? - c

I have the following code:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
void print_usage()
{
printf("%s\n", "usage");
}
int file_exist (char *filename)
{
struct stat buffer;
return (stat (filename, &buffer) == 0);
}
int parse_parameters(int argc, char *argv[], char** in)
{
unsigned int i1 = 1; // 0 is the filename
for (; i1 < argc; ++i1)
{
if( 0 == strcmp("-h", argv[i1]) )
{
print_usage();
return 0;
}
else if( 0 == strcmp("-i", argv[i1]) )
{
*in = malloc( sizeof(char) * strlen(argv[++i1]) + 1 );
strcpy(*in, argv[i1]);
continue;
}
else
{
print_usage();
return 1;
}
}
return 0;
}
int main(int argc, char *argv[])
{
if( argc != 3 )
{
print_usage();
return 0;
}
char* in = NULL;
int parse = parse_parameters(argc, argv, &in);
if ( 0 != parse )
return parse;
printf("in: %s\n", in);
FILE* finput = NULL ;
if (file_exist(in))
finput = fopen(in, "r");
if (finput == NULL) {
perror("fopen");
exit(1);
}
free(in);
fclose(finput);
return 0;
}
After running it with valgrind with following parameters:
./main -i input
I get the following:
==30977== Memcheck, a memory error detector
==30977== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==30977== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==30977== Command: ./main -i input
==30977==
in: input
fopen: No such file or directory
==30977==
==30977== HEAP SUMMARY:
==30977== in use at exit: 6 bytes in 1 blocks
==30977== total heap usage: 2 allocs, 1 frees, 574 bytes allocated
==30977==
==30977== 6 bytes in 1 blocks are still reachable in loss record 1 of 1
==30977== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30977== by 0x400946: parse_parameters (main.c:31)
==30977== by 0x4009E7: main (main.c:54)
==30977==
==30977== LEAK SUMMARY:
==30977== definitely lost: 0 bytes in 0 blocks
==30977== indirectly lost: 0 bytes in 0 blocks
==30977== possibly lost: 0 bytes in 0 blocks
==30977== still reachable: 6 bytes in 1 blocks
==30977== suppressed: 0 bytes in 0 blocks
==30977==
==30977== For counts of detected and suppressed errors, rerun with: -v
==30977== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Why is that ? If I try to pass in as char* then it won't get changed after the parse_parameters function.

Your program is exiting as a result of the exit (1) call, which occurs before you free (in). As a result you are seeing the valgrind message.

Related

simple c program output as expected, but valgrind memory lost

Context: Explanation of pointing to same address problem
compile:
gcc \
-Wpointer-arith -Wendif-labels \
-Wimplicit-fallthrough -Wmissing-format-attribute \
-Wcast-function-type -Wshadow=compatible-local \
-Wformat-security -Wno-format-truncation -Wno-stringop-truncation \
main.c &&./a.out dat/test.csv
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<errno.h>
enum {MAXB = 128, NELEM = 10};
typedef struct data_t{
char *name;
int id;
double balance;
}data_t;
int main(int argc,char **argv)
{
if(argc < 2){
printf("No file input.foramt a.out filename. %s\n",argv[1]);
exit(EXIT_FAILURE);
}
FILE *fp = fopen(argv[1],"r");
if(fp == NULL){
printf("file not found\n");
exit(EXIT_FAILURE);
}
char buffer[MAXB] = "";
const char *delim = ",\n";
int index = 0;
data_t **array = malloc(NELEM * sizeof *array);
if(!array){ /* validate EVERY allocation */
perror("malloc-array failed\n");
exit(EXIT_FAILURE);
}
/* protect the allocation bounds, you only have NELEM pointers */
while (index < NELEM && fgets(buffer,sizeof buffer,fp))
{
data_t customer;
size_t len = 0;
char *tmp; /* temporary pointer to use w/strtok() */
tmp = strtok(buffer,delim); /* token for name */
if(!tmp) /* validate token */
{
fputs("error: strtok() name.\n",stderr);
exit(EXIT_FAILURE);
}
len = strlen(tmp); /* get length */
customer.name = malloc(len+1); /* allocate for string */
if(!customer.name)
{
perror("malloc-customer.name\n");
exit(EXIT_FAILURE);
}
memcpy(customer.name,tmp, len +1); /* copy tmp to .name */
if(!(tmp = strtok(NULL,delim))) /* token & validations */
{
fprintf(stderr,"error: strtok() -id.\n");
exit(EXIT_FAILURE);
}
/* MINIMAL conversion validation with sscanf() */
if(sscanf(tmp,"%d",&customer.id) != 1){
fprintf(stderr,"error: invalid integer value for line[%d]\n",index+1);
continue;
/* exit(EXIT_FAILURE); */
}
if(!(tmp = strtok(NULL,delim))){
fprintf(stderr,"\nerror: strtok()-balance shuld have more line\n");
continue;
// exit(EXIT_FAILURE);
}
if(sscanf(tmp,"%lf", &customer.balance) != 1){
fprintf(stderr,"error: invalid float value for line[%d]\n", index+1);
/* exit(EXIT_FAILURE); */
continue;
}
array[index] = malloc(sizeof *array[index]); /* allocate struct */
if(!array[index]){ /* validate!! */
perror("malloc-array[index]");
exit(EXIT_FAILURE);
}
*array[index] = customer; /* assign struct */
index += 1;
}
fclose(fp);
int i;
printf("\nname\tid\t balance\n\n");
for(i = 0; i< index; i++)
printf("%s \t%d\t%f\n",array[i]->name,array[i]->id,array[i]->balance);
for(i = 0; i< index; i++)
{
if(array[i]->name)
free(array[i]->name); /* free allocated block for name */
if(array[i])
free(array[i]); /* free allocated array index */
}
free(array);
exit(EXIT_FAILURE);
}
cat dat/test.csv returns
name,id,balance
test1,11,1.2334
test2,12,1.133
test3,13,1.3334
test4,14,1.4334
command valgrind -s --leak-check=full ./a.out dat/test.csv output:
==494197== Memcheck, a memory error detector
==494197== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==494197== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==494197== Command: ./a.out dat/test.csv
==494197==
error: invalid integer value for line[1]
name id balance
test1 11 1.233400
test2 12 1.133000
test3 13 1.333400
test4 14 1.433400
==494197== Memcheck, a memory error detector
==494197== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==494197== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==494197== Command: ./a.out dat/test.csv
==494197==
error: invalid integer value for line[1]
name id balance
test1 11 1.233400
test2 12 1.133000
test3 13 1.333400
test4 14 1.433400
==494197==
==494197== HEAP SUMMARY:
==494197== in use at exit: 5 bytes in 1 blocks
==494197== total heap usage: 13 allocs, 12 frees, 5,797 bytes allocated
==494197==
==494197== 5 bytes in 1 blocks are definitely lost in loss record 1 of 1
==494197== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==494197== by 0x10951D: main (in /home/jian/helloc/a.out)
==494197==
==494197== LEAK SUMMARY:
==494197== definitely lost: 5 bytes in 1 blocks
==494197== indirectly lost: 0 bytes in 0 blocks
==494197== possibly lost: 0 bytes in 0 blocks
==494197== still reachable: 0 bytes in 0 blocks
==494197== suppressed: 0 bytes in 0 blocks
==494197==
==494197== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Invalid read using valgrind

After a compilation with no warnings and errors for my file reorg.c, I am running the program using Valgrind and I am getting the following output. I am trying to understand why I am getting a segmentation fault but I can't really find something wrong with line 35:
Memcheck, a memory error detector
==29338== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==29338== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==29338== Command: ./reorg /opt/lsde/dataset-sf100/
==29338==
==29338== Invalid read of size 2
==29338== at 0x109398: main (reorg.c:35)
==29338== Address 0x12cb4008 is not stack'd, malloc'd or (recently) free'd
==29338==
==29338==
==29338== Process terminating with default action of signal 11 (SIGSEGV)
==29338== Access not within mapped region at address 0x12CB4008
==29338== at 0x109398: main (reorg.c:35)
==29338== If you believe this happened as a result of a stack
==29338== overflow in your program's main thread (unlikely but
==29338== possible), you can try to increase the size of the
==29338== main thread stack using the --main-stacksize= flag.
==29338== The main thread stack size used in this run was 8388608.
==29338==
==29338== HEAP SUMMARY:
==29338== in use at exit: 15,280 bytes in 10 blocks
==29338== total heap usage: 10 allocs, 0 frees, 15,280 bytes allocated
==29338==
==29338== LEAK SUMMARY:
==29338== definitely lost: 5,120 bytes in 5 blocks
==29338== indirectly lost: 0 bytes in 0 blocks
==29338== possibly lost: 0 bytes in 0 blocks
==29338== still reachable: 10,160 bytes in 5 blocks
==29338== suppressed: 0 bytes in 0 blocks
==29338== Rerun with --leak-check=full to see details of leaked memory
==29338==
==29338== For lists of detected and suppressed errors, rerun with: -s
==29338== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)
This is the code of the reorg.c program.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "utils.h"
Person *person_map;
unsigned int *knows_map;
unsigned short *interest_map;
unsigned long person_num = 0;
int main(int argc, char *argv[]) {
unsigned long file_length;
interest_map = (unsigned short *) mmapr(makepath(argv[1], "interest", "bin"), &file_length);
printf("amin1");
knows_map = (unsigned int *) mmapr(makepath(argv[1], "knows", "bin"), &file_length);
printf("amin2");
person_map = (Person *) mmapr(makepath(argv[1], "person", "bin"), &file_length);
printf("amin3");
knows_map = (unsigned int *) mmapr(makepath(argv[1], "knows", "bin"), &file_length);
printf("knows");
person_map = (Person *) mmapr(makepath(argv[1], "person", "bin"), &file_length);
printf("person");
person_num = file_length/sizeof(person_map);
int counter=0;
FILE* fp_knows2 = fopen(makepath(argv[1], "knows2", "bin"), (char*) "w");
FILE* fp_person2 = fopen(makepath(argv[1], "person2", "bin"), (char*) "w");
long knows2_bytesize;
int *knows2_map;
int *person2_map;
long person2_bytesize;
for(long i=0; i<person_num; i++) {
for(long j = 0; j < person_map[i].knows_n; j++) {
int friend = knows_map[person_map[i].knows_first+j]; // person in my knows-list
if (person_map[friend].location == person_map[i].location) {
counter++;
fwrite(&friend, 1,sizeof(int), fp_knows2);
}
}
if(counter > 0){
fwrite(&person_map[i], 1, sizeof(int), fp_person2);
}
counter=0;
}
fclose(fp_knows2);
fclose(fp_person2);
person2_map = (int*) mmapr(makepath(argv[1], "person2","bin"), &person2_bytesize);
knows2_map = (int*) mmapr(makepath(argv[1], "knows2","bin"), &knows2_bytesize);
return 0;
}
And this is the code of the utils.h program that am including in:
#define REPORTING_N 1000000
#define LINEBUFLEN 1024
typedef unsigned long byteoffset;
typedef unsigned int entrycount;
typedef struct {
unsigned long person_id;
unsigned short birthday;
unsigned short location;
unsigned long knows_first;
unsigned short knows_n;
unsigned long interests_first;
unsigned short interest_n;
} Person;
void parse_csv(char* fname, void (*line_handler)(unsigned char nfields, char** fieldvals)) {
long nlines = 0;
FILE* stream = fopen(fname, "r");
if (stream == NULL) {
fprintf(stderr, "Can't read file at %s\n", fname);
exit(-1);
}
char line[LINEBUFLEN];
char* tokens[10];
unsigned int col, idx;
tokens[0] = line;
while (fgets(line, LINEBUFLEN, stream)) {
col = 0;
// parse the csv line into array of strings
for (idx=0; idx<LINEBUFLEN; idx++) {
if (line[idx] == '|' || line[idx] == '\n') {
line[idx] = '\0';
col++;
tokens[col] = &line[idx+1];
} // lookahead to find end of line
if (line[idx+1] == '\0') {
break;
}
}
(*line_handler)(col, tokens);
nlines++;
if (nlines % REPORTING_N == 0) {
printf("%s: read %lu lines\n", fname, nlines);
}
}
fclose(stream);
}
FILE* open_binout(char* filename) {
FILE* outfile;
outfile = fopen(filename, "wb");
if (outfile == NULL) {
fprintf(stderr, "Could not open %s for writing\n", filename);
exit(-1);
}
return outfile;
}
unsigned short birthday_to_short(char* date) {
unsigned short bdaysht;
char dmbuf[3];
dmbuf[2] = '\0';
dmbuf[0] = *(date + 5);
dmbuf[1] = *(date + 6);
bdaysht = atoi(dmbuf) * 100;
dmbuf[0] = *(date + 8);
dmbuf[1] = *(date + 9);
bdaysht += atoi(dmbuf);
return bdaysht;
}
void* mmapr(char* filename, byteoffset *filelen) {
int fd;
struct stat sbuf;
void *mapaddr;
if ((fd = open(filename, O_RDONLY)) == -1) {
fprintf(stderr, "failed to open %s\n", filename);
exit(1);
}
if (stat(filename, &sbuf) == -1) {
fprintf(stderr, "failed to stat %s\n", filename);
exit(1);
}
mapaddr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (mapaddr == MAP_FAILED) {
fprintf(stderr, "failed to mmap %s\n", filename);
exit(1);
}
*filelen = sbuf.st_size;
return mapaddr;
}
char* makepath(char* dir, const char* file, const char* ext) {
char* out = (char*) malloc(1024), *sep = (char*) "";
if (strlen(dir) && dir[strlen(dir)-1] != '/') sep = (char*) "/";
sprintf(out, "%s%s%s.%s", dir, sep, file, ext);
return out;
}

segmentation fault (c language)

While trying to recover jpgs from a raw file in week4 of CS50 course , I got this seg fault error which I can't understand why or how it is caused, all I can tell is that according to valgrind line 110 causes this issue
I am fairly new to c language
int main(int argc, char *argv[])
{
// check if one command arg is passed
if (argc > 2 )
{
printf("Usage: ./recover image\n");
return 1;
}
// try to open file to read from
FILE *file = fopen(argv[1], "r");
if (!file)
{
return 1;
}
BYTE bytes[512];
int x =0 ;
char num[10];
FILE* output =NULL;
while (fread(&bytes, 512, 1, file) == 1)
{
// first step create file name
sprintf(num, "%03i.jpg",x);
// check for start of jpg file
if (bytes[0]==0xff && bytes[1] ==0xd8 && bytes[2]== 0xff && (bytes[3] & 0xf0) == 0xe0 )
{
printf("Found file {%i}", x);
output = fopen(num , "w");
fwrite(&bytes ,512 ,1 ,output);
x++;
}
else
{
fwrite(&bytes , 512 , 1 , output);
}
}
return 0;
}
output of valgrind
==12934== Invalid read of size 4
==12934== at 0x4A1C521: fwrite (iofwrite.c:37)
==12934== by 0x4014CA: main (recover.c:110)
==12934== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==12934==
==12934==
==12934== Process terminating with default action of signal 11 (SIGSEGV)
==12934== Access not within mapped region at address 0x0
==12934== at 0x4A1C521: fwrite (iofwrite.c:37)
==12934== by 0x4014CA: main (recover.c:110)
==12934== If you believe this happened as a result of a stack
==12934== overflow in your program's main thread (unlikely but
==12934== possible), you can try to increase the size of the
==12934== main thread stack using the --main-stacksize= flag.
==12934== The main thread stack size used in this run was 8388608.
==12934==
==12934== HEAP SUMMARY:
==12934== in use at exit: 472 bytes in 1 blocks
==12934== total heap usage: 2 allocs, 1 frees, 4,568 bytes allocated
==12934==
==12934== LEAK SUMMARY:
==12934== definitely lost: 0 bytes in 0 blocks
==12934== indirectly lost: 0 bytes in 0 blocks
==12934== possibly lost: 0 bytes in 0 blocks
==12934== still reachable: 472 bytes in 1 blocks
==12934== suppressed: 0 bytes in 0 blocks
==12934== Rerun with --leak-check=full to see details of leaked memory
==12934==
==12934== For lists of detected and suppressed errors, rerun with: -s
==12934== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
zsh: segmentation fault valgrind ./recover card.raw
take this one
int main(int argc, char *argv[])
{
// check if one command arg is passed
if (argc > 2 )
{
printf("Usage: ./recover image\n");
return 1;
}
// try to open file to read from
FILE *file = fopen(argv[1], "r");
if (!file)
{
return 1;
}
BYTE bytes[512];
int x =0 ;
char num[10];
FILE* output =NULL;
while (fread(bytes, 512, 1, file) == 1)
{
// check for file start
if (bytes[0]==0xff && bytes[1] ==0xd8 && bytes[2]== 0xff && (bytes[3] & 0xf0) == 0xe0 )
{
if (output)
{
fclose(output);
}
// create file name
sprintf(num, "%03i.jpg",x);
printf("Found file {%i}\n", x);
output = fopen(num , "w");
fwrite(&bytes ,512 ,1 ,output);
x++;
}
else if (output)
{
fwrite(bytes , 512 , 1 , output);
}
}
if(output)
{
fclose(output);
}
return 0;
}
notice the use of fclose(output); to close file descriptors, as noted by Marek R
changing
else
{
fwrite(&bytes , 512 , 1 , output);
}
to
else if (output)
{
fwrite(&bytes , 512 , 1 , output);
}
generates the pictures
thanks to Marek R for mentioning the if file is opened comment

POSIX semaphores - cannot determine what causes segmentation fault

I'm working on the sleeping barber problem (using FIFO queue and shared memory), and I have a problem. I try to run this program just to see what is shown, however, I get segmentation fault every time. In the code I check, if semaphores are created successfully, if shared memory is created properly, but the program crashing must come from different place, which I cannot seem to find. I also tried to use Valgrind but what I got is:
Valgrind for the newer version of code:
However, when I try to run the code I still get segfault
==187== Memcheck, a memory error detector
==187== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==187== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==187== Command: ./barber
==187==
Error while executing program, invalid amount of arguments==187==
==187== HEAP SUMMARY:
==187== in use at exit: 0 bytes in 0 blocks
==187== total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==187==
==187== All heap blocks were freed -- no leaks are possible
==187==
==187== For lists of detected and suppressed errors, rerun with: -s
==187== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==124== Memcheck, a memory error detector
==124== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==124== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==124== Command: ./barber
==124==
==124== Invalid read of size 1
==124== at 0x1094DD: main (in /mnt/c/users/Czaro/ubuntu/lab6posix/barber)
==124== Address 0x2 is not stack'd, malloc'd or (recently) free'd
==124==
==124==
==124== Process terminating with default action of signal 11 (SIGSEGV)
==124== Access not within mapped region at address 0x2
==124== at 0x1094DD: main (in /mnt/c/users/Czaro/ubuntu/lab6posix/barber)
==124== If you believe this happened as a result of a stack
==124== overflow in your program's main thread (unlikely but
==124== possible), you can try to increase the size of the
==124== main thread stack using the --main-stacksize= flag.
==124== The main thread stack size used in this run was 8388608.
glut==124==
==124== HEAP SUMMARY:
==124== in use at exit: 125 bytes in 4 blocks
==124== total heap usage: 5 allocs, 1 frees, 1,149 bytes allocated
==124==
==124== LEAK SUMMARY:
==124== definitely lost: 0 bytes in 0 blocks
==124== indirectly lost: 0 bytes in 0 blocks
==124== possibly lost: 0 bytes in 0 blocks
==124== still reachable: 125 bytes in 4 blocks
==124== suppressed: 0 bytes in 0 blocks
==124== Reachable blocks (those to which a pointer was found) are not shown.
==124== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==124==
==124== For lists of detected and suppressed errors, rerun with: -s
==124== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault
I'd greatly appreciate every kind of help!
The code for barber (newer version, with changes given by #AndrewHenle looks like this:
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "functions.h"
#include <sys/mman.h>
#include <unistd.h>
int main(char* argv[], int argc)
{
if(argc < 2){
printf("Error while executing program, invalid amount of arguments");
return 0;
}
sem_t *barber;
sem_t *queue;
int seats;
int sharedmem, waitRoomSize;
struct Queue waitroom;
barber = sem_open("Barber", O_CREAT | O_RDWR, 0666, 1);
if((barber == SEM_FAILED)){
printf("Error while creating semaphore for barber");
exit(1);
}
queue = sem_open("Queue", O_CREAT | O_RDWR, 0666, 1);
if((queue == SEM_FAILED)) {
printf("Error while creating semaphore for queue");
exit(1);
}
seats = atoi(argv[1]);
void *space;
queueinit(waitroom, seats);
sharedmem = shm_open("Queue", O_RDWR, 0666);
if(sharedmem==-1){
printf("Error while getting shared memory");
exit(1);
}
waitRoomSize = ftruncate(sharedmem, sizeof(waitroom));
if((waitRoomSize ==-1)){
printf("Error while getting size");
exit(1);
}
space = mmap(NULL, sizeof(struct Queue), PROT_READ | PROT_WRITE, MAP_SHARED, sharedmem, 0);
if((space == MAP_FAILED)){
printf("B³¹d podczas mapowania pamiêci");
exit(1);
}
while(1)
{
printf("Starting work...");
sem_wait(queue);
sem_post(queue);
if(isEmpty(waitroom)) {
sem_wait(barber);
printf("Falling asleep \n");
sem_post(barber);
printf("Waking up \n");
}
sem_wait(queue);
sem_post(queue);
int id = get(waitroom);
printf("Customer: %d, please sit on the chair", id);
printf("I start making haircut: %d", id);
sleep(2);
printf("Finished making haircut for: %d", id);
}
sem_close(barber);
sem_unlink("Barber");
sem_close(queue);
sem_unlink("Queue");
}
Previous version:
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "functions.h"
#include <sys/mman.h>
#include <unistd.h>
int main(char* argv, int argc)
{
sem_t *barber;
sem_t *queue;
int seats;
int sharedmem, waitRoomSize;
struct Queue waitroom;
barber = sem_open("Barber", O_CREAT | O_RDWR, 0666, 1);
if((barber == SEM_FAILED)){
printf("Error while creating semaphore for barber");
exit(1);
}
queue = sem_open("Queue", O_CREAT | O_RDWR, 0666, 1);
if((queue == SEM_FAILED)) {
printf("Error while creating semaphore for queue");
exit(1);
}
seats = atoi(argv[1]);
void *space;
queueinit(waitroom, seats);
if((sharedmem = shm_open("Queue", O_RDWR, 0666)==-1)){
printf("Error while getting shared memory");
exit(1);
}
if((waitRoomSize = ftruncate(sharedmem, sizeof(waitroom))==-1)){
printf("Error while getting size");
exit(1);
}
if((space = mmap(NULL, sizeof(struct Queue), PROT_READ | PROT_WRITE, MAP_SHARED, sharedmem, 0) == MAP_FAILED)){
printf("Błąd podczas mapowania pamięci");
exit(1);
}
while(1)
{
printf("Starting work...");
sem_wait(queue);
sem_post(queue);
if(isEmpty(waitroom)) {
sem_wait(barber);
printf("Falling asleep \n");
sem_post(barber);
printf("Waking up \n");
}
sem_wait(queue);
sem_post(queue);
int id = get(waitroom);
printf("Customer: %d, please sit on the chair", id);
printf("I start making haircut: %d", id);
sleep(2);
printf("Finished making haircut for: %d", id);
}
sem_close(barber);
sem_unlink("Barber");
sem_close(queue);
sem_unlink("Queue");
}
The FIFO queue is implemented like this:
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
#include <stdlib.h>
#include <unistd.h>
struct Queue{
int* elems;
int qsize;
int head;
int tail;
int capacity;
};
void queueinit(struct Queue q, int capacity)
{
q.elems = malloc(capacity*(sizeof(int)));
q.capacity = capacity;
q.head = 0;
q.qsize = 0;
q.tail = capacity-1;
}
int isFull(struct Queue q)
{
return (q.qsize == q.capacity);
}
int isEmpty(struct Queue q)
{
return (q.qsize == 0);
}
void push(struct Queue q, int val)
{
if(isFull(q)){
printf("Kolejka pe³na");
return;
}
q.tail = (q.tail +1) % q.capacity;
q.elems[q.tail] = val;
q.qsize = q.qsize +1;
printf("%d zajmuje miejsce w kolejce", val);
}
int get(struct Queue q)
{
if(isEmpty(q))
{
printf("kolejka pusta");
return -1;
}
int val = q.elems[q.head];
q.head = (q.head +1) % q.capacity;
q.qsize = q.qsize -1;
printf("%d opuszcza zak³ad", val);
}
#endif // FUNCTIONS_H_INCLUDED

Correctly free alsa mixer resources

I'm writing some simple Alsa init code to setup a mixer, which I'll be using to set volume, etc. However, even basic code has memory leaks, despite using suggesting memory freeing method like snd_config_update_free_global(). If someone could check the snippet out and let me know what I'm missing, it would be greatly appreciated. Thanks!
#include <alsa/asoundlib.h>
#include <stdio.h>
#include <stdlib.h>
void PrintAlsaError(const char * str, int error_code) {
fprintf(stderr, str, snd_strerror(error_code));
}
int main() {
snd_mixer_t * handle;
snd_mixer_selem_id_t * sid;
snd_mixer_elem_t * elem;
const char * card = "default";
int error_code;
if ((error_code = snd_mixer_open(&handle, 0)) < 0) {
PrintAlsaError("unable to open handle, error: %s\n", error_code);
return -1;
} else if ((error_code = snd_mixer_attach(handle, card)) < 0) {
PrintAlsaError("unable to attach to card, error: %s\n", error_code);
snd_mixer_close(handle);
return -1;
} else if ((error_code = snd_mixer_selem_register(handle, NULL, NULL)) < 0) {
PrintAlsaError("unable to register handle, error: %s\n", error_code);
snd_mixer_close(handle);
return -1;
} else if ((error_code = snd_mixer_load(handle)) < 0) {
PrintAlsaError("unable to load handle, error: %s\n", error_code);
snd_mixer_close(handle);
return -1;
}
snd_mixer_selem_id_alloca(&sid);
if (!sid) {
fprintf(stderr, "couldn't get selem id\n");
}
if (!(elem = snd_mixer_first_elem(handle))) {
fprintf(stderr, "no elements in mixer\n");
}
snd_mixer_selem_get_id(elem, sid);
snd_mixer_close(handle);
snd_config_update_free_global();
return 0;
}
Here's the valgrind output:
==8389== HEAP SUMMARY:
==8389== in use at exit: 69,442 bytes in 193 blocks
==8389== total heap usage: 6,912 allocs, 6,719 frees, 591,848 bytes allocated
==8389==
==8389== LEAK SUMMARY:
==8389== definitely lost: 0 bytes in 0 blocks
==8389== indirectly lost: 0 bytes in 0 blocks
==8389== possibly lost: 0 bytes in 0 blocks
==8389== still reachable: 69,442 bytes in 193 blocks
==8389== suppressed: 0 bytes in 0 blocks
==8389== Rerun with --leak-check=full to see details of leaked memory
==8389==
==8389== For counts of detected and suppressed errors, rerun with: -v
==8389== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Resources