Symptoms

When accessing an STL object created in one DLL or EXE through a pointer or reference in a different DLL or EXE, you may experience an access violation or other serious program errors including the appearance of data corruption or data loss.

Cause

Most classes in the Standard C++ Libraries use static data members directly or indirectly. Since these classes are generated through template instantiation, each executable image (usually with DLL or EXE file name extensions) will contain its own copy of the static data member for a given class. When a method of the class that requires the static data member is executed, it uses the static data member in the executable image in which the method code resides. Since the static data members in the executable images are not in sync, this action could result in an access violation or data may appear to be lost or corrupted.

Resolution

  1. Export accessor methods from the executable image that created the STL object. These methods wrap the required functionality of the STL object. In this way, the STL object will only be directly accessed inside a single executable image. For example, suppose MyProgram.EXE needs to get the next element in deque<MyClass> that resides in MyLibrary.DLL. MyLibrary.DLL could export an accessor method, MyClass* DequeNextItem (/*...*/). Then MyProgram.EXE could execute this method to get the next item in the deque. See the code sample below for a more complete example.

    This option works for STL objects that are either global, static, or static data members of a class that are not exported from a DLL. This option will not work for non-static data members of a class that are exported from a DLL or for automatic data.

  2. Export the template class instantiation from one executable image and import it into the other executable images. For example, if MyLibrary.DLL passes a pointer to vector<MyClass> back to a function in MyProgram.EXE, then export the classes MyClass and vector<MyClass> from MyLibrary.DLL. Then import these classes into MyProgram.EXE. By doing this, you will have one copy of the static class members residing in MyLibrary.DLL. For more information about exporting and importing STL, click the following article number to view the article in the Microsoft Knowledge Base:
    168958How to export STL components inside and outside of a class

Status

This behavior is by design.

More Information

Steps to reproduce the behavior

   //---------------------------------------------------------
// AVEXE.CPP
// Compile options needed: /GX
#pragma warning (disable : 4786)
#include <map>
#include <string>
#include <stdio.h> __declspec(dllimport)
std::map<int,std::string>* GiveMeAMap(int n); __declspec(dllimport)
void ShowMeTheMap(std::map<int,std::string> *amap); __declspec(dllexport)
const char* MapItemX (std::map<int,std::string> *m, int x); int main () { // Create the map in the DLL
int x = 6;
std::map<int,std::string> *p = GiveMeAMap(x); // Display the contents of the map from the DLL
printf("Showing contents from the DLL\n");
ShowMeTheMap(p); // Display the contents of the map from the EXE
// using the accessor function from the DLL so we
// aren't directly accessing the map
printf("Showing contents from the EXE using accessor\n");
int i = x;
while (i--) {
printf("%d = %s\n",i,MapItemX(p,i));
} // Access Violation when accessing the map that
// was created in the DLL from the EXE
printf("Showing contents from the EXE directly\n");
while (x--) {
printf("%d = %s\n",x,(*p)[x].c_str());
} return 0;
} //---------------------------------------------------------
// AVDLL.CPP
// Compile options needed /GX
#pragma warning (disable : 4786)
#include <map>
#include <string>
#include <stdlib.h> // Create the map here in the DLL
__declspec(dllexport)
std::map<int,std::string>* GiveMeAMap(int n) {
std::map<int,std::string> *m = new std::map<int,std::string>;
while(n--) {
char b[33];
itoa(n,b,2);
(*m)[n] = std::string(b);
}
return m;
} // We can access the map without error from the executable
// image where the map was created
__declspec(dllexport)
void ShowMeTheMap(std::map<int,std::string> *p) {
int x = p->size();
while (x--) {
printf("%d = %s\n",x,(*p)[x].c_str());
}
} // An accessor method to return the associated C string
// for key x
__declspec(dllexport)
const char* MapItemX (std::map<int,std::string> *m, int x) {
return (*m)[x].c_str();
}
 
Properties

Article ID: 172396 - Last Review: Sep 2, 2005 - Revision: 1

You may experience an access violation when you access an STL object through a pointer or reference in a different DLL or EXE的更多相关文章

  1. 如何捕获access violation异常

    文章目录 access violation的由来 access violation的实例 Win32 exception SEH异常与C++标准异常 捕获方法 1.access violation的由 ...

  2. 动态调用DLL函数有时正常,有时报Access violation的异常

    动态调用DLL函数有时正常,有时报Access violation的异常 typedef int (add *)(int a,int b); void test() {     hInst=LoadL ...

  3. 解决 “access violation at address xxxxxxxxx”错误

    在进行磁盘整理的时候,打开Foxmail的时候出现了“access violation at address32383137”错误 和“access violation at address00000 ...

  4. STM32 KEIL不能输入仿真引脚端口error 65: access violation at 0x40021000 : no 'read' permission

    使用MDK自己创建一个STM32F103ZE核的项目 加入源码后编译,正常,在线仿真单步执行出现如下问题 error 65: access violation at 0x40021000 : no ' ...

  5. QDomDocument Access violation writing location

    今天犯了一个非常2的错误! 为了将面板参数保存起来,选择用QDomDocument构造Dom树,然后用doc.toString()方法返回符合xml格式的QString.如: QString CutF ...

  6. Access Violation at address 00000000.Read of address 00000000 解决办法

    是数组越标或没有初始化某个对象之类的问题,搂住细细检查一下代码, 使用指针前未做检查,而这个指针未初始化. 可能是new后没有delete,这样出现溢出的可能性比较大     检查代码或者跟踪试试 使 ...

  7. u-boot TFTP: &#39;Access violation&#39; (2)

    今天做tftp下载时间会遇到以下问题. --->8--- Load address: 0x20000000 Loading: * TFTP error: 'Access violation' ( ...

  8. laravel migrate时报错:Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes

    今天在学习laravel的路由模型绑定时,在按照文档执行php artisan migrate时报错. In Connection.php line 664: SQLSTATE[42000]: Syn ...

  9. std::vector push_back报错Access violation

    C/C++ code   ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include < ...

随机推荐

  1. js 3行代码,最简易实现div效果悬浮

    简易实现浮动效果的首要因素是:获取滚动条距离浏览器顶部的距离,下面直接贴代码: <!DOCTYPE html> <html> <head> <meta cha ...

  2. redis使用场景之位操作(大数据处理)

    在学习redis的过程了,看到了redis还能用于大数据处理,具体场景如下: 腾讯10亿用户,要几个毫秒内查询到某个用户是否在线,你能怎么做?千万别说给每个用户建立一个key,然后挨个记(你可以算一下 ...

  3. [C语言] 数据结构-离散存储链表定义

    离散存储[链表] 1.定义: n个节点离散分配,彼此通过指针相连 每个节点只有一个前驱节点 只有一个后续节点 首节点没有前驱节点,尾节点没有后续节点 2.专业术语: 首节点:第一个有效节点 尾节点:最 ...

  4. SpringBoot(二) Core Features: SpringApplication

    参考 文档: SpringApplication

  5. 撩课-Web大前端每天5道面试题-Day22

    1.mvvm和mvc区别?它和其它框架(jquery)的区别是什么?哪些场景适合? mvc和mvvm其实区别并不大. 都是一种设计思想. 主要就是mvc中Controller演变成mvvm中的view ...

  6. JVM学习网址(收集总结)

    1.文章分类 - JVM调优总结   JVM综合调优汇总 星火燎原智勇 2018-08-16 11:11 阅读:8 评论:0 JVM调优04-概括总结 星火燎原智勇 2017-01-08 23:28 ...

  7. 网络编程: 基于TCP协议的socket, 实现一对一, 一对多通信

    TCP协议  面向连接 可靠的 面向字节流形式的 tcp是基于链接的,必须先启动服务端,然后再启动客户端去链接服务端 TCP协议编码流程: 服务器端:                 客户端 实例化对 ...

  8. --num 与 num-- 的区别

    递增++和递减--操作符都属于一元操作符. 只能操作一个值的运算符是一元操作符,一元操作符是ECMscript中最简单的操作符. 递增.递减操作符介绍 递增.递减操作符有两个版本:前置型和后置型.顾名 ...

  9. PHPCMS V9标签循环嵌套调用数据的方法

    PHPCMS V9的标签制作以灵活见长,可以自由DIY出个性的数据调用,对于制作有风格有创意的网站模板很好用,今天就介绍一个标签循环嵌套方法,可以实现对PC标签循环调用,代码如下: 在此文件里/php ...

  10. 判断css文件是否加载完成

    function cssReady(fn, link) { var d = document, t = d.createStyleSheet, r = t ? 'rules' : 'cssRules' ...