Ошибка ошибки сегментации (дамп ядра) в именованных каналах - PullRequest
0 голосов
/ 03 сентября 2018

Пытаясь реализовать обратную строку, используя именованные каналы в C ++ и python в Ubuntu, я получаю ошибку Segmentation Fault (Core Dumped), когда пытаюсь принять пользовательский ввод. Программа работает без нареканий, когда строка предопределена.

Ниже приведена программа для записи на C ++, которая записывает в файл:

#include <fcntl.h>
#include <iostream>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string>
#include <string.h>
using namespace std;
int main()
{
    int fd;
    char *myfifo = "/home/Desktop/myFile";

    /* create the FIFO (named pipe) */
    mkfifo(myfifo, 0666);

    /* write message to the FIFO */
    fd = open(myfifo, O_WRONLY);
    char const*msg;
    cout << "Please enter string to be reversed: ";
    cin>>msg;

   // msg="This is the string to be reversed";
   // The above line works fine which is pre-defined string.

    write(fd, msg, strlen(msg)+1);
    close(fd);

    /* remove the FIFO */
    unlink(myfifo);

    return 0;
}

Ниже приведена моя программа Reader на Python:

import os
import sys

path= "/home/Desktop/myFile"

fifo=open(path,'r')
str=fifo.read()
revstr=str[::-1]
print(revstr)
fifo.close()

После одновременного выполнения вышеуказанных файлов я получаю следующий вывод:

Writer.cpp =>

Please enter string to be reversed: qwerty
Segmentation fault (core dumped)

Reader.py => No Output, Blank

После поиска в Google я обнаружил, что это означает попытку доступа к части памяти, доступной только для чтения.

Но как мне убрать эту ошибку, чтобы получить строку от пользователя? Нужно ли менять права доступа к файлу, чтобы он записывался во время чтения? Что может сработать?

1 Ответ

0 голосов
/ 03 сентября 2018

Этот документирует перегрузку operator>>, которую вы в данный момент используете:

template<class CharT, class Traits>
basic_istream<CharT,Traits>& operator>>(basic_istream<CharT,Traits>& st, CharT* s);

что на самом деле означает примерно

basic_istream<char>& operator>>(basic_istream<char>& st, char* s);

(где вы называете это с st = cin и s = msg).

В документации сказано, что это перегрузка

... извлекает последовательные символы и сохраняет их в последовательных местах массива символов, на первый элемент которого указывает s

но s (или msg) не указывает на массив, где вы можете хранить эти символы. Это неинициализировано, и хранение чего-либо там без инициализации, чтобы оно указывало на какое-то действительное местоположение, является Неопределенное поведение .

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

Использование перегрузки std::string вместо этого позволяет классу строк позаботиться о хранении, сколько бы байтов не было прочитано, потому что std::string (в отличие от простого массива) может расти сам по мере необходимости.

...