Ошибка получения ошибки сегментации (дамп ядра) в именованных каналах

Пытаясь реализовать обратную строку с использованием именованных каналов в 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 я обнаружил, что это означает попытку доступа к части памяти, доступной только для чтения.

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

msg не имеет связанного объем памяти. Использовать std::string для легкой жизни?
Bathsheba 03.09.2018 12:23

У вас есть указатель msg, но вы нигде не указываете его.

Some programmer dude 03.09.2018 12:26

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

Useless 03.09.2018 13:28
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
3
546
1

Ответы 1

Этот документирует используемую вами перегрузку 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).

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

... extracts successive characters and stores them at successive locations of a character array whose first element is pointed to by s

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

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

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

Другие вопросы по теме