Получаете плохой адрес, когда я разветвляюсь? - PullRequest
0 голосов
/ 26 ноября 2018

Итак, у меня есть три файла: Pellets.c, Fish.c и SwimMill.c.SwimMill вызывает Pellets and Fish, которые должны раскошелиться.Тем не менее, когда я пытаюсь разветвить пеллеты, я получаю сообщение об ошибке: «Не удалось разложить пеллет: неправильный адрес».Кто-нибудь знает, в чем проблема?

include.h

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>

#define SHM_SIZE 1000

int shmid;
int *shm;
pid_t fish;
pid_t pellet;


void attachSharedMemory() {
  key_t key = ftok("SwimMill.c", 'b'); //generate random key
  shmid = shmget(key, SHM_SIZE, IPC_CREAT|0666);
  shm = shmat(shmid, NULL, 0);

}

SwimMill.c

// Uses both fish and pellets, 30 seconds, then print it out
// Create pellets at random intervals, from 0x80
// Eating --> Get rid of most significant bit
// Use shared memory for fish and pellet position only
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include "include.h"

#define SHM_SIZE 1000

void printGrid(int*);
void handler(int);
void killProgram(pid_t, pid_t, int*, int);
pid_t fish;
pid_t pellet;

int main(int argc, char* argv[]) {

    int timer = 0;
    attachSharedMemory(); // from include.h
    signal(SIGINT, handler);


    // Initializing the shared memory to prevent segmentation fault
    // for (int i = 0; i < SHM_SIZE; i++){
    //  shm[i] = -1;
    // }
    srand(time(NULL));
    fish = fork();

    if (fish == -1) {
        perror("Fish fork failed1");
        exit(1);
    }   else if (fish == 0) {
        execv("Fish", argv);
        perror("Fish exec failed");
        exit(1);
    }
    while(timer <= 30){
        pellet = fork();
        if (pellet == -1) {
            perror("Pellet Fork failed1");
            exit(1);
        }   else if (pellet == 0) {
            execv("Pellets", argv);
            perror("Pellets Fork failed");
            exit(1);
        }
        printGrid(shm);
        sleep(1);
        printf("Timer: %d\n", timer);
        timer++;
    }

    killProgram(fish, pellet, shm, shmid);
    getchar(); // Pause consol
    return 0;
}


void printGrid(int* shm) {
    int row = 10;
    int column = 10;
    char (*stream)[row][column]; //2D Dimensional array, fish can only move last row of 2d

    //Initializing grid first
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < column; j++) {
            (*stream)[i][j] = '~';
        }
    }
    printf("Fish: %d \n", shm[0]);
    printf("Shm2 is: %d \n", shm[1] );
    for (int k = 1; k < 20; k++) {
        (*stream)[shm[k]/10][shm[k]%10] = 'O'; // pellets
    }
    (*stream)[shm[0]/10][shm[0]%10] = 'Y'; // Fish
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < column; j++) {
            printf("%c ", (*stream)[i][j]);
        }
        printf("\n");
    }

}

void killProgram(pid_t fish, pid_t pellet, int *shm, int shmid) {
    kill(fish,SIGUSR1);
    kill(pellet, SIGUSR1);
    sleep(5);
    shmdt(shm);
    shmctl(shmid, IPC_RMID, NULL);
    printf("Program finished! \n");
}

void handler(int num ) {
    kill(fish,SIGUSR1);
    kill(pellet, SIGUSR1);
    shmdt(shm);
    shmctl(shmid, IPC_RMID, NULL);
    perror(" Interrupt signal is pressed!! \n");

    exit(1);
}

Pellets.c

// Multiple pellets
//Process ID, position, eaten/misse
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include "include.h"

#define SHM_SIZE 1000

void handler(int);
void eatPellet();
void missPellet();

int main(int argc, char* argv[]) {
  signal(SIGINT, handler);

  attachSharedMemory();
  srand(time(NULL));

  int i = 1; // 1 - 19 are pellets
  for (; i < 20; i++) {
    int pelletPosition = rand() % 9 ; // random number from 0 - 9
    if (shm[i] == -1){
      // printf("hello %d \n", pelletPosition);
      shm[i] = pelletPosition;
    }
    break;
  }
  while(1) {
    printf("helloasd %d \n", shm[i]);
    printf("i: %d \n", i);
    if (shm[i] < 90) {
      shm[i] += 10;
    }
    else if (shm[i] == shm[0]) {
      eatPellet();
      printf("Position: %d\n", shm[i] );
      break;
      // EATEN and KILL
    }
    else {
      // KIll process, terminate
      missPellet();
      printf("Position: %d\n", shm[i] );
      break;
    }
    // printf("%d\n",shm[i] );
    i++;
    sleep(1);
  }
  shmdt(shm);
  return 0;
}

void handler(int num) {
    shmdt(shm);
    exit(1);
}

Iсмотрел на другие вопросы переполнения стека, и кажется, что они проблемы, потому что они не заканчиваются с NULL?Я думаю, что проблема заключается в Pellets.c, но я не могу понять это.Спасибо.

...