【问题标题】:Memory access violation error c++内存访问冲突错误c ++
【发布时间】:2018-02-27 11:37:14
【问题描述】:

我正在尝试使用多个隐蔽渠道交换消息。 所以,基本上,首先我需要选择我想用于通信的频道,然后选择我想与之聊天的用户的“destination_ip”,然后

进程消息()

被调用。现在,要从一个通道移动到另一个通道,我必须关闭现有连接,然后使用我要使用的新通道打开一个新连接。我下面的代码被修改为在关闭连接后继续使用相同的通道并且只包含你需要的东西。

#include <channelmanager.hpp>
#include <thread>
#include <iostream>
#include <boost/test/unit_test.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <stdio.h>
#include <string.h>
#include <fstream>
#include <openssl/hmac.h>

struct CommunicationFixture {
    CommunicationFixture() {
        channelmanager.setErrorStream(&cout);
        channelmanager.setOutputStream(&cout);
        destination_ip = "";
        channel_id = channelmanager.getChannelIDs()[0];

    }
    library::ChannelManager channelmanager;
    vector<string> last_adapters;
    string destination_ip;
    string channel_id = "";


    int processMessage(string message) {
        if (message.compare("exit") == 0) {
            channelmanager.closeConnection(destination_ip);
            return 1;
        }
        vector<string> arguments;
        boost::split(arguments, message, boost::is_any_of(" "), boost::token_compress_on);
        if (arguments[0].compare("argument") == 0) {
            if (arguments.size() < 2) {
                cout << "Not enough arguments" << endl;
                return 0;
            }
            string argument_list = arguments[1];
            for (unsigned int i = 2; i < arguments.size(); i++) {
                argument_list += " " + arguments[i];
            }
            channelmanager.setChannelArguments(destination_ip, argument_list);
            cout << "Set channel argument to '" << argument_list << "'." << endl;
            return 0;
        }
        if (message.compare("help") == 0) {
            cout << "Help not available in chat mode. Close chat first with 'exit'" << endl;
            return 0;
        }


        channelmanager.openConnection(destination_ip, channel_id);
        channelmanager.sendMessage(destination_ip, message);

        return 0;

    }

    int close(string destination){
        cout << "closing.." << endl;
        channelmanager.closeConnection(destination); //I believe i have the error because of this!
        return 0;
    }

};


BOOST_FIXTURE_TEST_SUITE(communication, CommunicationFixture)

BOOST_AUTO_TEST_CASE(basic_communication) {

    selectAdapterId(0);
    cout << "Test" << endl << endl;
    printCommands();
    cout << "Enter your command:" << endl;
    string command;
    int code = 0;
    while (code != 2) {
        std::getline(cin, command);
        code = processCommand(command);
        if (code == 1) {
            // chat
            cout << "chat started.." << endl;
            int chatCode = 0;


            while (chatCode != 1) {
                std::getline(cin, message);
                close(destination_ip);
                chatCode = processMessage(message);
                channelmanager.setErrorStream(&cout);
            }
            cout << "chat ended." << endl;
        }
    }



}

BOOST_AUTO_TEST_SUITE_END()

请注意,我认为该错误是由于

函数关闭()

因为没有它我不会收到任何错误。并且错误不会立即发生,而是在交换一些消息之后发生。这是错误:

未知位置(0):致命错误:在 “communication/basic_communication”:内存访问冲突 地址:0x00000024:故障地址无映射 communicationTest.cpp(325):最后一个检查点:“basic_communication” 测试条目

【问题讨论】:

  • 自动测试通常不与用户交互。
  • @molbdnilo 因为我在 close() 之后调用了 processMessage(),所以在关闭连接后会立即打开一个新连接。请注意,代码可以正常运行 1 分钟,然后崩溃。
  • 对不起,我没注意。
  • 加载你的调试器!

标签: c++ memory-access


【解决方案1】:

当您尝试访问一个未初始化的变量时会发生内存访问冲突,在本例中为channelmanager

我只能看到您在 processMessage() 方法中初始化 channelmanager 并且在初始化 channelmanager 之前关闭连接,因为它发生在:

close(destination_ip);
chatCode = processMessage(message);

要么更改初始化,要么不要在processMessage() 方法之前关闭它。

【讨论】:

  • 即使我不调用close() 并在channelmanager.openConnection(destination_ip, channel_id); 之前在processMessage() 函数中使用channelmanager.closeConnection(destination_ip);,我仍然会收到错误消息!
  • processMessage() 中没有初始化。而channelmanager 看起来像一个类——你不能在没有初始化的情况下实例化它,即使是通过默认构造函数。
  • @LightnessRacesinOrbit 我不太明白你在说什么。是的,channelmanager 是一个类。那么,我应该怎么做才能解决这个问题呢?
【解决方案2】:

内存访问冲突也称为分段错误(或 segfault),当程序尝试访问不存在或无法访问的内存位置时发生。我们称之为试图访问非法内存位置。那个记忆要么不存在,要么我们不被允许触摸它。

如果用户的第一个输入是'exit',它将调用

if (message.compare("exit") == 0) {
     channelmanager.closeConnection(destination_ip);
     return 1;
}  

在这种情况下,destination_ip 未初始化。

【讨论】:

  • 是的,你是对的。它已被初始化。为误读代码道歉。
  • destination_ip 也已初始化。这是一个字符串。它有一个默认构造函数。
  • 是的,但它是一个空字符串。
  • 我现在编辑了我的问题,但正如我所说,在调用 processMessage() 之前选择了destination_ip。所以,它不是一个空字符串。
  • @ArchieYalakki:空字符串和未初始化的字符串是完全不同的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多