C - 得到错误***堆栈粉碎检测***

时间:2018-05-04 22:51:16

标签: c fork stack-overflow semaphore

我知道这可能是一个重复的问题,但我还没有找到解决问题的方法。

我想做什么

我试图用C语言写一个成长型社会的模拟,其中有两种类型的人,A和B(在我的例子中有2个人)。

  • A接受"参与提案"来自B
  • 使用邮件队列处理ABgestore之间的通信
  • 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
  9. 请注意 personB.c

    中的代码行
    • printf("1----------------------------\n");
    • printf("2----------------------------\n");

    由于错误,第二行无法打印。

    提前感谢您的帮助。

    输出继电器

    output error, stack smashing detected

    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)
    

    修改

    我应该像这样链接和编译吗?

    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 :(得分:-2)

我&#39;重大&#39;编辑此答案并删除不再应用的语句,因为OP修改了发布的代码。

注意:修改发布的代码时,一般情况下,请勿修改原始发布的代码,而应将修改后的代码作为编辑发布。对于当前的问题,建议只发布交错代码,也许通过

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

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

在main()function that repeatedly calls系统中()建议编译步骤启用警告。至少使用这些编译选项:

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

注意:上述参数必须在compile语句中,而不是link语句。

为了使调试更加轻松,建议compilelink选项包括:

-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 );