C - получение ошибки *** Обнаружено разрушение стека *** - PullRequest
0 голосов
/ 05 мая 2018

Я знаю, что это может быть повторяющийся вопрос, но я пока не могу найти решение своей проблемы.

Что я хочу сделать

Я пытаюсь написать на C своего рода симуляцию растущего общества, где есть 2 типа людей, A и B (2 человека в моем примере).

  • A принимает «предложения о помолвке» от B
  • Связь между A, B и gestore обрабатывается с помощью очередей сообщений
  • gestore определяет атрибуты каждого "человека", а затем создает их с помощью execve, передавая каждый атрибут в качестве аргумента
  • Существует основная очередь сообщений, в которой каждый процесс A отправляет сообщение со своей информацией и ключом своей личной очереди сообщений.
  • B читает из основной очереди сообщений и затем связывается с A, используя данный ключ, найденный в сообщении

Я под Linux Mint 18,3 32 бит.

проблема

Всегда выдает ошибку Обнаружено разрушение стека в файле

Мои файлы

header.h

#ifndef _HEAD_H
#define _HEAD_H

#include <unistd.h>
#include <sys/msg.h>

#define OFFSET 1000000

union semun {
    int val;
    struct semid_ds *buf;
    unsigned short *array;
    struct seminfo *__buf;
};

struct person{
    char type;
    int name;
    unsigned long genome;
};

struct msg_text {
    pid_t pid;
    char type;
    int name;
    unsigned long genome;
    int key_of_love;
    pid_t partner;
};

struct mymsg { 
    long mtype;
    struct msg_text mtxt;
};

int initSemAvailable(int, int);
int initSemInUse(int, int);
int reserveSem(int, int);
int releaseSem(int, int);
#endif

header.c

#include <sys/sem.h>
#include <sys/types.h>
#include "header.h"

int initSemAvailable(int semId, int semNum)
{
    union semun arg;
    arg.val = 1;
    return semctl(semId, semNum, SETVAL, arg);
}

int initSemInUse(int semId, int semNum)
{
    union semun arg;
    arg.val = 0;
    return semctl(semId, semNum, SETVAL, arg);
}

int reserveSem(int semId, int semNum) {
    struct sembuf sops;
    sops.sem_num = semNum;
    sops.sem_op = -1;
    sops.sem_flg = 0;
    return semop(semId, &sops, 1);
}

int releaseSem(int semId, int semNum) {
    struct sembuf sops;
    sops.sem_num = semNum;
    sops.sem_op = 1;
    sops.sem_flg = 0;
    return semop(semId, &sops, 1);
}

gestore.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "header.h"

#ifndef MAX_PEOPLE
#define MAX_PEOPLE 5
#endif

#ifndef GENES
#define GENES 1000000
#endif

#ifndef BIRTH_DEATH
#define BIRTH_DEATH 5
#endif

#define SIZE_N 15

//handle signals
struct sigaction sa;
sigset_t my_mask;
void handle_signal(int);

//remove every IPC object
void remove_all();

//terminate every child
void terminate_children();

//free memory
void free_all();

//print every field of message
void print_msg(struct mymsg);

unsigned int init_people;
int * child_status;
pid_t * initial_children;
char * child_name;
char * child_genome;
char * child_sem;
char * child_sem2;
char * child_msgq_a;
//message queue
struct msqid_ds msq;
int msgq_a;
//semaphores
int sem_init_people;
int sem_init_people2;

int main(void)
{
    init_people = 0;//will contain initial number of people
    int i = 0;
    pid_t child;//fork value
    unsigned long random_ulong = 0;
    child_name = (char *)calloc(SIZE_N, sizeof(char));
    child_genome = (char *)calloc(SIZE_N, sizeof(char));
    child_sem = (char*)calloc(SIZE_N, sizeof(char));
    child_sem2 = (char*)calloc(SIZE_N, sizeof(char));
    child_msgq_a = (char*)calloc(SIZE_N, sizeof(char));
    char * args[8] = {};
    char * envs[] = {NULL};

    if( child_name == NULL || child_genome == NULL
    || child_sem == NULL || child_sem2 == NULL
    || child_msgq_a == NULL){
        perror("there's a null variable");
        exit(EXIT_FAILURE);
    }

    //handle signals
    sa.sa_handler = &handle_signal;
    sa.sa_flags = 0;
    sigemptyset(&my_mask);
    sigaction(SIGALRM, &sa, NULL);
    sigaction(SIGUSR1, &sa, NULL);

    printf("\nSTARTING SIMULATION\n\n");

    init_people = 2;
    initial_children = (pid_t *)calloc(init_people,
    sizeof(pid_t));

    //create 2 semaphores

    sem_init_people = semget(IPC_PRIVATE, 1,
    0666|IPC_CREAT|IPC_EXCL);
    if( sem_init_people == -1 ){
        if(errno == EEXIST){
            if( semctl(sem_init_people, 0,
            IPC_RMID, NULL) == -1 ){
                perror("rm sem_init_people");
                exit(EXIT_FAILURE);
            }
        }else{
            perror("semget init_people");
            exit(EXIT_FAILURE);
        }
    }

    sem_init_people2 = semget(IPC_PRIVATE, 1,
    0666|IPC_CREAT|IPC_EXCL);
    if( sem_init_people2 == -1 ){
        if(errno == EEXIST){
            if( semctl(sem_init_people2, 0,
            IPC_RMID, NULL) == -1 ){
                perror("remove sem_init_people2");
                exit(EXIT_FAILURE);
            }
        }else{
            perror("semget sem_init_people2");
            exit(EXIT_FAILURE);
        }
    }

    //create message queue
    msgq_a = msgget(IPC_PRIVATE, 0666|IPC_CREAT|IPC_EXCL);
    if(msgq_a == -1){
        if( errno == EEXIST ){//if exists
            // delete message queue
            if( msgctl(msgq_a, IPC_RMID, &msq) == -1 )
                perror("rmid");
        }else
            perror("msgget queue A");
        exit(EXIT_FAILURE);
    }

    //initialize sem_init_people to 0 (reserved)
    if( initSemInUse(sem_init_people, 0) == -1 ){
        perror("initSemInUse for sem_init_people");
        exit(EXIT_FAILURE);
    }

    //initialize sem_init_people2 to 0 (reserved)
    if( initSemInUse(sem_init_people2, 0) == -1 ){
        perror("initSemInUse for sem_init_people");
        exit(EXIT_FAILURE);
    }

    //RWX permissions for people processes
    if( chmod("./A", 0777) != 0 ){
        perror("chmod person A");
        exit(EXIT_FAILURE);
    }
    if( chmod("./B", 0777) != 0 ){
        perror("chmod person B");
        exit(EXIT_FAILURE);
    }

    printf("Generating %u people\n\n", init_people);

    //generate initial population
    for(i = 0; i < init_people; i++){

        //TYPE
        if( i%2 == 0 )
            args[0] = "./A";
        else
            args[0] = "./B";

        //NAME
        if( sprintf(child_name, "%d", i+65) < 0 ){
            perror("printf NAME execve");
            exit(EXIT_FAILURE);
        }
        args[1] = child_name;

        //GENOME
        if( sprintf(child_genome, "%lu",
        (long)i+100000) < 0 ){
            perror("sprintf GENOME execve");
            exit(EXIT_FAILURE);
        }
        args[2] = child_genome;

        //semaphore 1
        if( sprintf(child_sem, "%d",
        sem_init_people) < 0 ){
            perror("sprintf sem_init_prople execve");
            exit(EXIT_FAILURE);
        }
        args[3] = child_sem;

        //semaphore 2
        if( sprintf(child_sem2, "%d",
        sem_init_people2) < 0 ){
            perror("sprintf sem_init_prople2 execve");
            exit(EXIT_FAILURE);
        }
        args[4] = child_sem2;

        //msg queue
        if( sprintf(child_msgq_a, "%d", msgq_a) < 0 ){
            perror("sprintf child_msgq_a execve");
            exit(EXIT_FAILURE);
        }
        args[5] = child_msgq_a;

        //final argument
        args[6] = NULL;


        switch(child = fork()){

            case -1:{ //error
                perror("fork init_people");
                exit(EXIT_FAILURE);
            }

            case 0:{//child

                if( execve(args[0], args, envs) == -1 ){
                    perror("execve");
                }
                //execve didnt't work
                exit(EXIT_FAILURE);
            }

            default:{//parent

                printf("[type:%c][name:%c][pid:%d][gen:%s][sem1:%s]\
[sem2:%s][msgq:%s]\n",
                    args[0][2],
                    atoi(args[1]),
                    (int)child,
                    args[2],
                    args[3],
                    args[4],
                    args[5] );

                //add every child in the array
                initial_children[i] = child;
            }
        }//-switch
    }//-for

    //wait for every child to be ready to start
    for(i = 0; i < init_people; i++){
        if( reserveSem(sem_init_people, 0) != 0 ){
            perror("reserveSem sem_init_people");
            exit(EXIT_FAILURE);
        }
    }

    //allow every child to start
    for(i = 0; i < init_people; i++){
        if( releaseSem(sem_init_people2, 0) != 0 ){
            perror("releaseSem sem_init_people2");
            exit(EXIT_FAILURE);
        }
    }

    //wait for termination of every child
    if( waitpid(-1, child_status, (int)WNOHANG) == -1 ){
        perror("waitpid");
    }

    printf("Father is now waiting...\n");
    for(i = 0; i < 3; i++){
        sleep(3);
    }

    terminate_children();
    remove_all();
    free_all();

    return EXIT_SUCCESS;
}


void handle_signal(int signum)
{
    switch(signum){

        case SIGUSR1:{

            pid_t pidA = 0, pidB = 0;
            unsigned long genomeA = 0, genomeB = 0;
            struct mymsg msg1, msg2;
            int msg_flag = 0;

            //ignore sigusr1
            if( sigaddset(&my_mask, SIGUSR1) == -1 ){
                perror("sigaddset");
                exit(EXIT_FAILURE);
            }

            //read for every message
            while(msg_flag == 0){
                if( msgrcv(msgq_a, &msg1, sizeof(msg1),
                OFFSET+getpid(), IPC_NOWAIT) == -1 ){
                    if( errno == ENOMSG ){
                        msg_flag = -1;
                        printf("gestore is empty\n");
                    }else{ //random error happened
                        perror("msgrcv parent A and B");
                        exit(EXIT_FAILURE);
                    }
                }else{
                    print_msg(msg1);
                    msg_flag = 0;
                }

            }

            //do not ignore SIGUSR1
            if( sigdelset(&my_mask, SIGUSR1) == -1 ){
                perror("sigdelset");
                exit(EXIT_FAILURE);
            }

            break;
        }

        default:{}
    }
}

void terminate_children()
{
    int i = 0;
    for(i = 0; i < init_people; i++){
        if( kill(initial_children[i], 0) == 0 ){
            if( kill(initial_children[i], SIGTERM) == -1){
                perror("kill sigterm to child");
            }
        }
    }
}

void remove_all()
{
    //...
}

void free_all()
{
    //...
}

void print_msg(struct mymsg msg)
{
    printf("gestore rcv [mtype:%lu][pid:%d][type:%c]\
[name:%c][gen:%lu][key<3:%d][pid<3:%d]\n",
        msg.mtype,
        (int)msg.mtxt.pid,
        msg.mtxt.type,
        msg.mtxt.name,
        msg.mtxt.genome,
        msg.mtxt.key_of_love,
        (int)msg.mtxt.partner );
}

personA.c

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "header.h"

#define NMEMB 50

void accept_lover(int msgq, int love_msg_queue,
    struct mymsg love_letter, struct person myself);

void reject_lover(int, struct mymsg love_letter);

struct sigaction sa;
void handle_signal(int);

void print_rcvd_msg(struct mymsg);
void print_sent_msg(struct mymsg);

struct msqid_ds msq;
int love_msg_queue;

int main(int argc, char** argv)
{
    if(argc < 6){
        perror("A argc");
        exit(EXIT_FAILURE);
    }

    struct person myself;//info of A process
        myself.type = 'A';
        myself.name = (int)atoi(argv[1]);
        myself.genome = (unsigned long)atol(argv[2]);
    int sem_init_people, sem_init_people2;
        sem_init_people = (int)atoi(argv[3]);
        sem_init_people2 = (int)atoi(argv[4]);
    int msgq = atoi(argv[5]);
    struct mymsg msg_out, love_letter;
    struct msqid_ds msq;
    int engaged = -1;
    int count_refused = 0;

    sa.sa_handler = &handle_signal;
    sigaction(SIGTERM, &sa, NULL);

    //tell parent you're ready
    if( releaseSem(sem_init_people, 0) != 0 ){
        perror("releaseSem sem_init_people");
        exit(EXIT_FAILURE);
    }

    //wait for parent permission
    if( reserveSem(sem_init_people2, 0) != 0 ){
        perror("reserveSem sem_init_people2");
        exit(EXIT_FAILURE);
    }

    //create personal message queue of love
    love_msg_queue = msgget(IPC_PRIVATE,
    0666|IPC_CREAT|IPC_EXCL);
    if( love_msg_queue == -1 ){
        if( errno == EEXIST ){//if exists
            // delete message queue
            if( msgctl(love_msg_queue,
            IPC_RMID, &msq) == -1 ){
                perror("rmid queue of love");
                exit(EXIT_FAILURE);
            }
        }else{
            perror("msgget queue of love");
            exit(EXIT_FAILURE);
        }
    }

    //create message with correct info of process A
    msg_out.mtype = myself.genome;
    msg_out.mtxt.pid = getpid();
    msg_out.mtxt.type = myself.type;
    msg_out.mtxt.genome = myself.genome;
    msg_out.mtxt.name = myself.name;
    msg_out.mtxt.key_of_love = love_msg_queue;
    msg_out.mtxt.partner = -1;

    //when A accepts B engaged = 0
    while(engaged != 0){

        //send info in message queue
        if( msgsnd(msgq, &msg_out, sizeof(msg_out), 0)
        == -1 ){
            if(errno == EINTR)
                perror("A caught a signal and failed \
a blocked msgsnd");
            else
                perror("A msgsnd"); 
            exit(EXIT_FAILURE);
        }
        print_sent_msg(msg_out);

        //wait for love letter from B
        if( msgrcv(love_msg_queue, &love_letter,
            sizeof(love_letter), 0, 0) == -1 ){
            perror("A msgrcv love letter from B");
            exit(EXIT_FAILURE);
        }
        print_rcvd_msg(love_letter);

        //accept B if..
        if( count_refused >= 2 ){
            engaged = 0;//B is good, EXIT loop
            accept_lover(msgq, love_msg_queue,
            love_letter, myself);
            printf("[A:%d]accepted[B:%d]\n",(int)getpid(),
                (int)love_letter.mtxt.pid);
        }else{
            reject_lover(love_msg_queue,love_letter);
            printf("[A:%d] refused %d times\n",
                (int)getpid(),count_refused+1);
            count_refused++;
        }

    }

    pause();
    return EXIT_SUCCESS;
}

void handle_signal(int signum)
{
    switch(signum){

        case SIGTERM:{
            printf("A SIGTERM from parent\n");

            // delete message queue if exists
            if( (msgctl(love_msg_queue, IPC_RMID,
                &msq) == -1) && (errno != EIDRM) ){
                perror("A rmid 2");
            }
            break;
        }

        default:{}
    }
}

void accept_lover(int msgq, int love_msg_queue,
    struct mymsg love_letter, struct person myself)
{
    struct mymsg
        msg_to_B, msg_to_gestore1, msg_to_gestore2;

    //tell B you accept his request (key_of_love = 0)
    msg_to_B.mtype = love_letter.mtype; //pid of B
    msg_to_B.mtxt.pid = getpid();
    msg_to_B.mtxt.type = 'A';
    msg_to_B.mtxt.name = myself.name;
    msg_to_B.mtxt.genome = myself.genome;
    msg_to_B.mtxt.key_of_love = 0; //0 means accepted
    msg_to_B.mtxt.partner = -1;

    //send msg to B in queue of love
    if( msgsnd(love_msg_queue, &msg_to_B,
        sizeof(msg_to_B), 0) == -1 ){
        perror("A msgsnd to B accept lover");
        exit(EXIT_FAILURE);
    }
    print_sent_msg(msg_to_B);

    //tell gestore that A accepted a request from B
        //send message with info of A
        //send message with info of B

    //A
    msg_to_gestore1.mtype = OFFSET + getppid();
    msg_to_gestore1.mtxt.pid = getpid();
    msg_to_gestore1.mtxt.type = 'A';
    msg_to_gestore1.mtxt.name = myself.name;
    msg_to_gestore1.mtxt.genome = myself.genome;
    msg_to_gestore1.mtxt.key_of_love = 0;
    msg_to_gestore1.mtxt.partner = love_letter.mtype;

    //B
    msg_to_gestore2.mtype = OFFSET + getppid();
    msg_to_gestore2.mtxt.pid = love_letter.mtype;
    msg_to_gestore2.mtxt.type = 'B';
    msg_to_gestore2.mtxt.name = love_letter.mtxt.name;
    msg_to_gestore2.mtxt.genome = love_letter.mtxt.genome;
    msg_to_gestore2.mtxt.key_of_love = 0;
    msg_to_gestore2.mtxt.partner = getpid();

    //send msg B
    if( msgsnd(msgq, &msg_to_gestore2,
        sizeof(msg_to_gestore2), 0) == -1 ){
        perror("A msg_to_gestore2");
        exit(EXIT_FAILURE);
    }

    //send msg A
    if( msgsnd(msgq, &msg_to_gestore1,
        sizeof(msg_to_gestore1), 0) == -1 ){
        perror("A msg_to_gestore1");
        exit(EXIT_FAILURE);
    }

    print_sent_msg(msg_to_gestore2);
    print_sent_msg(msg_to_gestore1);

    /*messages for gestore have mtype=OFFSET+father_pid
    so that others can't read messages with mtype greater
    than OFFSET and father can directly receive messages
    knowing both OFFSET and his pid. */
}

void reject_lover(int love_msg_queue,
    struct mymsg love_letter)
{
    love_letter.mtxt.key_of_love = -1;
    if( (msgsnd(love_msg_queue, &love_letter,
        sizeof(love_letter), 0) == -1) ){
        perror("A error refusing B in msgsnd");
        exit(EXIT_FAILURE);
    }
    print_sent_msg(love_letter);
}

void print_rcvd_msg(struct mymsg msg)
{
    printf("A received [mtype:%lu][pid:%d][type:%c]\
[name:%c][gen:%lu][key<3:%d][pid<3:%d]\n",
        msg.mtype,
        (int)msg.mtxt.pid,
        msg.mtxt.type,
        msg.mtxt.name,
        msg.mtxt.genome,
        msg.mtxt.key_of_love,
        (int)msg.mtxt.partner );
}

void print_sent_msg(struct mymsg msg)
{
    printf("A sent [mtype:%lu][pid:%d][type:%c][name:%c]\
[gen:%lu][key<3:%d][pid<3:%d]\n",
        msg.mtype,
        (int)msg.mtxt.pid,
        msg.mtxt.type,
        msg.mtxt.name,
        msg.mtxt.genome,
        msg.mtxt.key_of_love,
        (int)msg.mtxt.partner );
}

personB.c

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include "header.h"

//send message to A process and wait for response
int flirt(struct mymsg msg, struct person myself);

void print_rcvd_msg(struct mymsg);
void print_sent_msg(struct mymsg);

int main(int argc, char** argv)
{
    if(argc < 6){
        perror("B argc");
        exit(EXIT_FAILURE);
    }

    struct person myself;
        myself.type = 'B';
        myself.name = (int)atoi(argv[1]);
        myself.genome = (unsigned long)atol(argv[2]);
    int sem_init_people, sem_init_people2;
        sem_init_people = (int)atoi(argv[3]);
        sem_init_people2 = (int)atoi(argv[4]);
    int love_response = 1;
    int msgq = atoi(argv[5]);
    struct mymsg msg_out, msg_in;
    struct msqid_ds msq;

    //tell parent you're ready
    if( releaseSem(sem_init_people, 0) != 0 ){
        perror("release sem_init_people child proc");
        exit(EXIT_FAILURE);
    }

    //wait for parent permission to start living
    if( reserveSem(sem_init_people2, 0) != 0 ){
        perror("reserve sem_init_people2 child proc");
        exit(EXIT_FAILURE);
    }

    //when love_response is 0 A accepted B requests
    while(love_response != 0){

        //read message from queue
        if( msgrcv(msgq, &msg_in, sizeof(msg_in),
            -OFFSET, 0) < 1 ){
            perror("msgrcv");
            exit(EXIT_FAILURE);
        }
        print_rcvd_msg(msg_in);

        //send message to A process and wait for a response
        love_response = flirt(msg_in, myself);
        printf("2----------------------------\n");
    }
    //TODO: get ready to terminate
    return 0;
}

int flirt(struct mymsg msg, struct person myself)
{
    int queue_of_love = msg.mtxt.key_of_love;
    pid_t pid_A = msg.mtxt.pid;
    struct mymsg love_letter, msg_in;

    //create love letter
    love_letter.mtype = getpid();
    love_letter.mtxt.pid = getpid();
    love_letter.mtxt.type = 'B';
    love_letter.mtxt.name = myself.name;
    love_letter.mtxt.genome = myself.genome;
    love_letter.mtxt.key_of_love = -1;
    love_letter.mtxt.partner = -1;

    //send love letter to A to introduce yourself
    if( msgsnd(queue_of_love, &love_letter,
    sizeof(love_letter), 0) == -1 ){
        perror("B - msg send love");
        exit(EXIT_FAILURE);
    }
    printf("[B:%d] sent<3to [A:%d][mtype:%d][pid:%d]\
[type:%c][gen:%lu][name:%c][love:%d]\n",
        (int)getpid(), (int)pid_A,
        (int)love_letter.mtype,
        (int)love_letter.mtxt.pid,
        (int)love_letter.mtxt.type,
        (unsigned long)love_letter.mtxt.genome,
        love_letter.mtxt.name,
        love_letter.mtxt.key_of_love );

    //wait for response from A
    if( msgrcv(queue_of_love, &msg_in, sizeof(msg_in),
    getpid(), 0) == -1 ){
        perror("B can't wait for A's response");
        exit(EXIT_FAILURE);
    }
    print_rcvd_msg(msg_in);

    //if key of love 0 then accepted love request 

    printf("1 ----------------------------\n");
    return msg_in.mtxt.key_of_love;
}

void print_rcvd_msg(struct mymsg msg)
{
    printf("B received [mtype:%lu][pid:%d][type:%c]\
[name:%c][gen:%lu][key<3:%d][pid<3:%d]\n",
        msg.mtype,
        (int)msg.mtxt.pid,
        msg.mtxt.type,
        msg.mtxt.name,
        msg.mtxt.genome,
        msg.mtxt.key_of_love,
        (int)msg.mtxt.partner );
}

void print_sent_msg(struct mymsg msg)
{
    printf("B sent [mtype:%lu][pid:%d][type:%c]\
[name:%c][gen:%lu][key<3:%d][pid<3:%d]\n",
        msg.mtype,
        (int)msg.mtxt.pid,
        msg.mtxt.type,
        msg.mtxt.name,
        msg.mtxt.genome,
        msg.mtxt.key_of_love,
        (int)msg.mtxt.partner );
}

Скомпилировать и выполнить проект

  1. gcc -c header.c
  2. gcc -c personA.c header.c
  3. gcc -c personB.c header.c
  4. gcc -Wall -Wextra -Wconversion -pedantic -std=gnu11 -o A personA.o header.o
  5. gcc -Wall -Wextra -Wconversion -pedantic -std=gnu11 -o B personB.o header.o
  6. gcc -c gestore.c header.c
  7. gcc -Wall -Wextra -Wconversion -std=gnu11 -pedantic -o gestore gestore.o header.o
  8. ./gestore

Обратите внимание на строки кода в personB.c .

  • printf("1----------------------------\n");
  • printf("2----------------------------\n");

Вторая строка не печатается из-за ошибки.

Заранее спасибо за помощь.

Ouput

ошибка вывода, обнаружено разрушение стека

Valgrind valgrind --leak-check=full -v ./gestore дает этот вывод:

==8647== HEAP SUMMARY:
==8647==     in use at exit: 0 bytes in 0 blocks
==8647==   total heap usage: 7 allocs, 7 frees, 4,179 bytes allocated
==8647== 
==8647== All heap blocks were freed -- no leaks are possible
==8647== 
==8647== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==8647== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

EDIT

Должен ли я ссылаться и компилировать, как это?

  1. gcc -c -Wall -Wextra -Wconversion -std=gnu11 -ggdb header.c
  2. gcc -c -Wall -Wextra -Wconversion -std=gnu11 -ggdb personA.c header.c
  3. gcc -c -Wall -Wextra -Wconversion -std=gnu11 -ggdb personB.c header.c
  4. gcc -Wall -pedantic -ggdb -o A personA.o header.o
  5. gcc -Wall -pedantic -ggdb -o B personB.o header.o
  6. gcc -c -Wall -Wextra -Wconversion -std=gnu11 -ggdb gestore.c header.c
  7. gcc -Wall -pedantic -ggdb -o gestore gestore.o header.o

1 Ответ

0 голосов
/ 05 мая 2018

Я «сильно» отредактировал этот ответ и удалил заявления, которые больше не применялись, из-за того, что ОП модифицировали опубликованный код.

Примечание: при изменении отправленного кода, как правило, НЕ модифицируйте исходный отправленный код, а отправьте измененный код как РЕДАКТИРОВАТЬ. Для текущего вопроса предложите просто опубликовать чередующийся код, возможно, через

#if 0
    <old code> 
#else 
    <new code> 
#endif 

===================

в 'main () function that repeatedly calls system () `Предложите шаги компиляции для включения предупреждений. Как минимум используйте следующие параметры компиляции:

-Wall -Wextra -Wconversion -pedantic -std=gnu11

Примечание: вышеуказанные параметры должны быть в операторах compile, а не в операторах link.

и для упрощения отладки предлагаем варианты compile и link:

-ggdb

Кроме того, эта функция main() будет выполнять ВСЕ шаги каждый раз. Предложите написать makefile (и выполнить его с make), чтобы только те файлы, которые были изменены, будут перекомпилированы / повторно связаны

================

Примечание: есть настройка для очереди сообщений, которую код пропускает, поэтому будут использоваться значения по умолчанию. Эти значения по умолчанию могут быть неправильными для приложения OP.

Вот вырезка / вставка типичной установки очереди сообщений:

Примечание: код взят из приложения, содержащего множество очередей сообщений taskSelector выбирает, какая очередь сообщений

  /* initialize the queue attributes */
    attr[taskSelector].mq_flags   = 0;
    attr[taskSelector].mq_maxmsg  = 10;
    attr[taskSelector].mq_msgsize = 
        sizeof(struct structITC) 
        + dWEB_PAYLOAD_OVERHEAD  
        + dMAX_DATA_BLOCK_SIZE;
    attr[taskSelector].mq_curmsgs = 0;

================

отправленный код не может определить:

struct msqid_ds   -- oops it is defined in one of the header files

=================

Если проверка argc указывает, что пользователь не ввел все необходимые параметры командной строки, тогда код должен вывести сообщение USAGE и выйти. Нечто похожее на:

fprintf( stderr, "USAGE: %s ..description of all needed parameters..\n", argv[0] );
exit( EXIT_FAILURE );
...