在命名管道中获取分段错误(核心转储)错误

Posted

技术标签:

【中文标题】在命名管道中获取分段错误(核心转储)错误【英文标题】:Get Segmentation Fault (Core Dumped) error in Named Pipes 【发布时间】:2018-09-03 10:23:11 【问题描述】:

尝试在 Ubuntu 上使用 C++ 和 python 中的命名管道实现反向字符串,当我尝试接受用户输入时出现分段错误(核心转储)错误。预定义字符串时,程序可以完美运行。

以下是写入文件的 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;

以下是我的 Python Reader 程序:

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

谷歌搜索后,我发现这意味着尝试访问内存的只读部分。

但是,如何删除此错误以从用户那里获取字符串?我是否需要更改文件权限以使其在读取时写入?什么可能有效?

【问题讨论】:

msg 没有与之关联的内存。使用std::string 过轻松的生活? 你有一个指针msg,但你从来没有让它指向任何地方。 为了将来参考,您的输出显示生成了一个核心文件。学习在调试器中加载这些内容并亲自查看发生了什么是一项非常宝贵的实践技能(诚然,在这种情况下,basic_istream 模板可能会产生很多噪音,但值得一看)。 【参考方案1】:

This 记录了您当前正在使用的 operator&gt;&gt; 重载:

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 = cins = msg 调用它)。

文档说这种重载

... 提取连续字符并将它们存储在字符数组的连续位置,该字符数组的第一个元素由 s 指向

但是s(或msg)没有指向可以存储这些字符的数组。它未初始化,在其中存储任何内容而不将其初始化为指向某个有效位置是未定义行为

无论如何都不推荐这种重载,因为你不能安全地使用它。您事先不知道将读取多少字节,这意味着您无法为数组选择一个安全的大小来存储它们。

使用std::string overload 允许字符串类负责存储读取的字节数,因为std::string(与普通数组不同)可以根据需要自行增长。

【讨论】:

以上是关于在命名管道中获取分段错误(核心转储)错误的主要内容,如果未能解决你的问题,请参考以下文章

获取“分段错误核心转储”

键盘输入错误地重定向到命名管道读取

WCF 命名管道错误:管道已结束。 (109, 0x6d)

WCF命名管道另一个端点错误但没有其他端点?

创建命名管道时出现 Vbscript 错误

在 Ruby exec 语句中使用命名管道