Ошибка:Segmentation fault (core dumped): как можно исправить (Shared Memory) C++

267
11 января 2018, 22:26
#include <iostream>
#include <unistd.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
#include <queue>
int main()
{
    int ShmID = shmget(IPC_PRIVATE, 1024, IPC_CREAT | S_IRUSR | S_IWUSR);
    if(ShmID == -1)
    {
        std::cout << "Cannot create shared memory" << std::endl;
        return -1;
    }
    pid_t ChildPid = fork();
    if(ChildPid == -1)
    {
        std::cout << "Cannot fork" << std::endl;
        return -2;
    }
    std::queue<std::string>* str = (std::queue<std::string>*)shmat(ShmID, 0, 0);
    if(str == 0)
    {
        std::cout << "Cannot attach shared memory" << std::endl;
        return -3;
    }
    if(ChildPid == 0)
    {
        //CHild process
        str->push("hello");
        str->push("world");
        shmdt(str);
        return 0;
    }
    else
    {
        //parent process
        sleep(1);
        std::cout << str->front() << ' ';
        str->pop();
        std::cout << str->front() << ' ';
        str->pop();
        shmdt(str);
        shmctl(ShmID, IPC_RMID, 0);
    }
    return 0;
}
Answer 1

Ошибка слишком проста - Вы пытаетесь обращаться к объекту, который не создали

std::queue<std::string>* str = (std::queue<std::string>*)shmat(ShmID, 0, 0);

то есть, str указывает на память, но что там... а кто его знает. Если обычную структуру так можно размещать, то с++ классы нужно только через конструктор.

// получим указатель на память
void *p = shmat(ShmID, 0, 0);
// используем placement new для создания объекта по месту
std::queue<std::string> * str = new(p)std::queue<std::string>();

после такого изменения уже не падает. Но нужно не забыть вызвать деструктор (delete str;). И видимо его нужно вызвать только в одном из процессов. И самое главное - не вызвать его тогда, когда ещё другой процесс использует его.

Также нужно аккуратно посинхронизировать обращения к памяти, а то может быть очень весело - std::queue не ожидает, что он работает с разных процессов.

READ ALSO
Зачем нужны вложенные интерфейсы?

Зачем нужны вложенные интерфейсы?

Прогуливаясь по чужим кодам наткнулся на Класс, который содержит внутри интерфейсы:

281
Проход по двум коллекциям в Java 8 stream api

Проход по двум коллекциям в Java 8 stream api

Встал вопрос, как переписать проход по двум разным коллекциям с присвоением данных под Java 8 Stream api

214
Как изменить размер текста в jTextPane

Как изменить размер текста в jTextPane

Привет, когда я выполняю команду, тогда изменяется весь текстМожно ли как-то сделать что-бы изменялся размер только нового текста или того...

243