【问题标题】:Access Violation C++访问冲突 C++
【发布时间】:2011-09-04 02:27:16
【问题描述】:

我是 C++ 新手,我正面临访问冲突异常。 问题如下,我有包含结构的 backend.h 文件

struct Config
{
 ....
}conf;
get_conf();

backend.cpp 中的实现

Config get_conf()
{
return conf;
}

backend.cpp 和 backend.h 被编译生成一个 dll。 这个 dll 以这种方式包含在 VS 解决方案中

Config config = get_config();
Config *g_config = &config;

代码编译运行良好,但调用函数时抛出异常

First-chance exception at 0x75d6d36f in BA.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x002ec494..
First-chance exception at 0x75d6d36f in BA.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x002ebe28..
First-chance exception at 0x75d6d36f in BA.exe: Microsoft C++ exception: [rethrow] at memory location 0x00000000..
First-chance exception at 0x77962d37 in BA.exe: 0xC0000005: Access violation reading location 0x41ce5ab2.
Unhandled exception at 0x77962d37 in BA.exe: 0xC0000005: Access violation reading location 0x41ce5ab2.
The program '[4624] BA.exe: Native' has exited with code -1073741819 (0xc0000005).

我认为问题与指针和结构有关,请帮助我

【问题讨论】:

    标签: c++ visual-studio visual-studio-2010 pointers


    【解决方案1】:

    这个问题没有多大意义,它表明你可能应该从一本好书或教程开始了解基础知识(在头文件中声明变量可能不是一个好主意,函数声明在标题),您使用的整个术语是奇怪...

    无论如何,对于您现在遇到的特定问题,最好的建议是在调试器中运行应用程序,您会看到发生了什么。我的第一个猜测(看着水晶球)是您正在创建一个具有自动存储持续时间的 Config 对象在一个范围内(Config config = get_config(); --this creates 在当前范围内创建一个新对象是conf 对象的副本),然后获取指向它的指针(Config *g_config = &config; -- 指向当前范围内的config 对象,而不是全局conf),然后您将其传递并稍后在外部使用对象已经被销毁时的作用域。

    另一个选项是您正面临 初始化顺序失败,如果这两行不在上下文中,在这种情况下,您可能会尝试将尚未初始化的 conf 对象复制到config.

    std::bad_alloc 本身是一个异常,当new 分配内存失败时会抛出异常,如果系统资源不足(可能不是这里的问题)或请求不正确,就会发生这种情况。

    【讨论】:

    • 我认为它是第一个选项 .. 请原谅我,我是一名 java 开发人员,在 java 中返回对象是通过引用 .. 你到底有什么建议?
    • @Poka:这很大程度上取决于你想做什么(就像操作的语义一样),你为什么要获取指针?您需要先定义问题,然后才能找到解决方案。
    • 我只想获取结构体,然后通过我从用户那里获得的值设置其属性。
    • 一种常见的方法(也类似于 Java)是让 conf 对象成为 static 类成员(注意 static 也有其他含义),然后提供一个访问器,就像你在 Java 中一样......不需要让事情复杂化......
    • 因为目前没有类,我可以不声明类就使用它吗?
    【解决方案2】:

    如果您在标题中有此声明:

    struct Config
    {
     ....
    }conf;
    get_conf();
    

    那么它很可能相当于:

    struct Config { ... } ;
    Config conf;
    int get_conf();
    

    “可能”,因为在 C 中省略返回类型意味着返回类型是 int。在 C++ 中情况并非如此,但 MSVC 的编译器并不是真正符合标准的,所以它可能错过了这一点,尤其是。如果您禁用了警告。

    如果是这样,这可能会导致声明

    int get_conf();
    

    与定义相关联:

    Config get_conf() { ... }
    

    在源文件中。如果这个链接,这样的调用会使你的程序崩溃。

    【讨论】:

    • 我的错 .. 它的 Conf get_conf();我在打字时错过了它
    【解决方案3】:

    一个问题可能与结构的构造有关,当您编译时它可能会出现故障,即在结构创建/初始化之前,您正在为指针分配一些地址。

    因此,请确保所有 GLOBAL 数据创建/初始化都发生在同一个 cpp 编译单元中

    【讨论】:

      【解决方案4】:

      我没有要确认的编译器,但这至少是问题的一部分。标题中定义的conf 不起作用。如果你在两个 cpp 文件中使用了头文件,你会得到重复的符号。

      我猜科斯是正确的,为什么你会收到你用 seg 错误做的消息。您可能会收到一些警告(不要禁用它们)来确认这一点。

      我的另一个猜测是它可能正在尝试使用已声明但未初始化的变量。

      这就是我所期望的,假设您不想复制您的 Config 对象的一堆副本。

      // .h
      struct Config
      {
        // ...
      };
      Config &get_conf();
      
      // .cpp
      Config &get_conf()
      {
        static Config conf;
        return conf;
      }
      
      // some other file
      Config &conf = get_conf();
      conf.value = 5;
      

      【讨论】:

      • 我认为你所说的正是我所需要的,因为我只想要一个 conf 实例,但我试过了,不幸的是仍然是同样的异常,你怎么看?!
      • 我有一个问题..在函数内部声明conf不会导致问题,因为每次都会创建一个新的conf?
      • @Poka Yoke 不,当你声明 conf 为静态时,它只会在你第一次使用时创建。
      • @Poka Yoke 将调试消息放入构造函数和解构函数中,并了解它在做什么。您可能会遗漏一些小部分及其复制。
      猜你喜欢
      • 2018-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-31
      相关资源
      最近更新 更多