精华内容
下载资源
问答
  • 原因跟之前一样,对象在内存中已经被销毁,或者这个对象压根就没有被创建过。 慢慢的查找p_Screen在哪里被复制以及在哪里被销毁,最有效的方法就是看函数调用栈。 当我把断点设置在p_Screen赋值语句的那一行时,...

    无独有偶,我居然又碰上了同样的问题。

     

    原因跟之前一样,对象在内存中已经被销毁,或者这个对象压根就没有被创建过。

    慢慢的查找p_Screen在哪里被复制以及在哪里被销毁,最有效的方法就是看函数调用栈。

    当我把断点设置在p_Screen赋值语句的那一行时,发现还没运行到断点处就已经触发异常了,当然还有一种可能就是断点处的函数根本就没有被调用,而是跳过了这个函数而继续往后面执行了,不过我反复测试了一下,基本可以排除第二种可能。

    因此问题的症结就在指针在还没有被初始化或者赋值之前就被访问了(看到这个错误读者是否很无语?那就继续往下看吧    )

    解决方法:

    将指针的初始化提前到在访问之前就行。  

    总结:这个问题确实是很简单,但是我为什么会犯这种错误呢?

    我觉得。。。这不怪我,不怪我,真的不怪我!!!

    责任在于框架程序的响应方式(~。-) :

    因为我的项目用的是MFC的框架编程,所以框架内部的各个模块调用先后顺序真的并不是很明确,而且不是显示(与隐式相对)的通过一个成员函数调用另一个成员函数,各个函数之间没有明确的调用与被调用关系。

    他们之间是基于消息机制驱动的。

    系统(内核)发送消息(这些消息大部分是我的项目为了创建窗口或者申请资源的需要而自动要求内核发送的,只有一小部分是内核捕捉到的消息,比如鼠标点击、键盘按下等等),指定函数对其进行响应,因此函数之间的调用关系以及执行的先后顺序自然是捉摸不定的。

    像这种基于系统消息驱动的程序,在编程时一定要小心了,在消息函数的调用顺序不明确的时候,尽量不要把自己的赋值语句写进去,除非万不得已,为了实现功能的需要。

    否则就有可能出现你的变量还没有被初始化之前就已经被访问,那么就会出现程序运行时错误了。(慎用框架)

    当然框架也有很多优点,对于我们这种刚刚写项目的newbie,对设计模式也不太了解,框架可以帮我们构造好项目的一个基本模型,我们只需要了解整个框架的结构,向里面添加一些功能就好,这样整个项目也就条理清晰,可读性也强,也易于维护。

     

    转载于:https://www.cnblogs.com/xwmcc/p/10033706.html

    展开全文
  • c++无法访问内存

    千次阅读 2018-04-15 17:10:58
    在用c++写链表实现交并补时总是出现内存无法访问的问题,甚是苦恼,问题出在PrintList()这个函数上,而这个函数本身经调试并没有错误,可以看到下方的指针p内存不合法,也就是访问非法内存。于是通过断点检查传入...

    在用c++写链表实现交并补时总是出现内存无法访问的问题,甚是苦恼,

    问题出在PrintList()这个函数上,而这个函数本身经调试并没有错误,


    可以看到下方的指针p内存不合法,也就是访问了非法内存。

    于是通过断点检查传入参数的地址,发现linkunion方法中调用了Get()方法。

    void linkUnion(LinkList<int> &a, LinkList<int> b)

    {
    int flag = 0;
    for (int i = 0;i < b.Length();i++)
    {
    for (int j = 0; j < a.Length(); j++)
    {
    int x = a.Get(j);
    int y = b.Get(i);
    if (x == y)
    {
    flag = 1;
    }
    }
    if (flag == 0)
    {
    a.Insert(1, b.Get(i));

    }
    flag = 0;
    }

    }

    而在Get()方法中有一句语句为

    p = first->next;

    这样就导致在linkunion方法之后的linklist_b就已经被更改,所以会内存越界。


    以下贴上源代码:

    LinkList类:

    #pragma once
    #include<iostream>
    using namespace std;




    template<class DataType>
    struct Node
    {
    DataType data;
    Node<DataType> *next;
    };
    template<class DataType>
    class LinkList
    {
    public:
    LinkList() { first = new Node<DataType>; first->next = NULL; };
    LinkList(DataType a[], int n);



    ~LinkList()
    {
    Node<DataType> *p = new Node<DataType>;
    while (first != NULL)
    {
    p = first;
    first = first->next;
    delete p;
    }
    }
    //单表遍历算法
    void PrintList();
    //求链表长度
    int Length();
    void Insert(int i, DataType x);
    DataType Delete(int i);
    DataType Get(int i);


    friend void linkUnion(LinkList<int> &a, LinkList<int> b);
    friend void JosepCircle(LinkList<int> a, int interval);
    friend void linkIntersection(LinkList<int> a, LinkList<int> b);




    private:
    Node<DataType> *first;


    };


    template<class DataType>
    LinkList<DataType>::LinkList(DataType a[], int n)
    {
    first = new Node<DataType>;
    first->next = NULL;
    for (int i = 0; i < n; i++)
    {
    Node<DataType> *s = new Node<DataType>;
    s->data = a[i];
    s->next = first->next;
    first->next = s;


    }
    }






    template<class DataType>
    inline void LinkList<DataType>::PrintList()
    {
    Node<DataType> *p = first->next;


    while (p != NULL)
    {
    cout << p->data << endl;
    p = p->next;
    }

    }


    template<class DataType>
    int LinkList<DataType>::Length()
    {
    Node<DataType> *p = first->next;
    int count = 0;
    while (p != NULL)
    {


    p = p->next;
    count++;



    }


    return count;
    }


    template<class DataType>
    void LinkList<DataType>::Insert(int i, DataType x)
    {
    Node<DataType> *p = first;
    Node<DataType> *s = new Node<DataType>;
    for (int j = 0; j < i - 1; j++)
    {
    p = p->next;
    }
    s->data = x;
    s->next = p->next;
    p->next = s;


    }


    template<class DataType>
    inline DataType LinkList<DataType>::Delete(int i)
    {
    int j = 0;
    Node<DataType> *s = new Node<DataType>;
    Node<DataType> *p = new Node<DataType>;
    p = first->next;
    for (; j < i - 1; j++)
    {
    p = p->next;
    }
    if (p = NULL)
    {
    throw "溢出";
    }
    s = p->next;
    DataType temp = s->data;
    p->next = s->next;
    delete s;
    return temp;
    }


    template<class DataType>
    DataType LinkList<DataType>::Get(int i)
    {
    Node<DataType> *p = new Node<DataType>;
    int count = 1;
    p = first->next;
    while (p != NULL && count < i)
    {
    p = p->next;
    count++;
    }
    if (p == NULL)
    {
    throw "位置";
    }
    else
    {
    return p->data;
    }




    }

    LinkList_set.cpp:

    #include<iostream>
    #include"LinkList.h"
    using namespace std;
    void linkUnion(LinkList<int> &a, LinkList<int> b);
    void linkIntersection(LinkList<int> a, LinkList<int> b);
    void JosepCircle(LinkList<int> a,int interval);




    int main() {
    int a[5] = { 1,2,3,4,5 };
    int b[3] = { 4,5,6 };



    cout << '\n';
    cout << '\n';
    cout << "---------------------------------------------" << endl;
    cout << '\n';
    cout << '\n';


    LinkList<int> link_set1(a, 5);
    LinkList<int> link_set2(b, 3);


    LinkList<int> link_set3(a, 5);
    LinkList<int> link_set4(b, 3);
    try
    {
    link_set1.PrintList();
    link_set2.PrintList();


    cout << "单链表求交集" << endl;
    linkIntersection(link_set1, link_set2);

    cout << "单链表集合的并集" << endl;
    linkUnion(link_set3, link_set4);
    link_set3.PrintList();
    cout << "-------------------------------------------" << endl;












    }
    catch (char *c)
    {
    cout << c << endl;
    }






    system("PAUSE");


    }


    void linkUnion(LinkList<int> &a, LinkList<int> b)
    {
    int flag = 0;
    for (int i = 0;i < b.Length();i++)
    {
    for (int j = 0; j < a.Length(); j++)
    {
    int x = a.Get(j);
    int y = b.Get(i);
    if (x == y)
    {
    flag = 1;
    }
    }
    if (flag == 0)
    {
    a.Insert(1, b.Get(i));

    }
    flag = 0;
    }
    }


    void linkIntersection(LinkList<int> a, LinkList<int> b)
    {
    Node<int> *pb = new Node<int>;
    int flag = 0;
    int k = 0;
    Node<int> *pa = new Node<int>;

    LinkList<int> c;
    pa = a.first->next;
    pb = b.first->next;
    while (pa != NULL&&pb->next != NULL)
    {
    if (pa->data==pb->data)
    {
    c.Insert(1,pa->data);
    pa = pa->next;
    pb = pb->next;
    }
    else if (pa->data < pb->data)
    {
    pb = pb->next;
    }
    else if (pa->data > pb->data)
    {
    pa = pa->next;
    }
    }
    c.PrintList();





    }



    展开全文
  • C++C++内存管理

    千次阅读 2015-10-26 15:32:25
    我们要懂得好多东西,比如说最基本的面向对象编程思想,C++的封装、继承、多态机制,设计模式等,还有一个很重要的内容便是性能优化,像C/C++这种接近底层的语言,追求的就是性能,与之相关的一项内容便是内存管理,...

    写一个好的C++程序,我们要懂得好多东西,比如说最基本的面向对象编程思想,C++的封装、继承、多态机制,设计模式等,还有一个很重要的内容便是性能优化,像C/C++这种接近底层的语言,追求的就是性能,与之相关的一项内容便是内存管理,内存分配要合理,禁止破坏内存,不能有内存泄漏,操作不好的话,程序可能会越运行越慢,要不就是莫名其妙的crash,于是令人头疼的bug排查就这样开始了。

    1、内存分配方式

    在C++中,内存分为5个区:堆、栈、自由存储区、全局/静态存储区和常量存储区。

    :由new分配的内存块,分配成功后需要我们在适当的时候通过delete释放内存,为了避免内存泄漏,new和delete要成对使用。

    :执行函数时,函数内的局部变量(也叫自动变量)在栈上创建存储单元,函数执行结束时这些存储单元被自动释放,正因如此,函数返回局部变量的指针或引用是错误的。

    自由存储区:由malloc等函数分配的内存块,与堆类似,但内存释放是用free来完成的,malloc/free与new/delete的区别是前者属于库函数,而后者是操作符,除了分配/释放内存外,还会调用类的构造/析构函数。

    全局/静态存储区:全局变量和静态变量被分配到同一块存储区,生命周期和作用域与局部变量不同。

    常量存储区:顾名思义,内存中存放的是常量,不允许修改。

    2、堆与栈的区别

    堆、栈是经常提及的两个内存块,主要区别体现在以下几个方面。

    管理方式:栈由编译器自动管理,栈上的变量离开作用域之后内存被自动回收,而堆由我们自己管理,动态创建与释放内存,管理起来较为复杂。

    生长方向:从整体内存空间来看,栈位于高地址,向着内存地址减小的方向生长,堆位于低地址,向着内存地址增加的方向生长。

    空间大小:栈空间较小,堆空间则很大。

    碎片问题:栈的数据结构形式是后进先出,内存空间是一块连续的区域,不会有内存碎片问题,而堆则不同,频繁的new/delete会造成内存空间的不连续,从而产生堆碎片,影响程序性能。

    分配方式:栈有两种分配方式,静态分配和动态分配,静态分配由编译器完成,如局部变量的内存分配和释放,动态分配通过调用alloca函数实现,但内存释放是由编译器完成的。堆内存分配则都是动态分配,需要我们自己分配内存并进行内存释放。

    分配效率:栈的分配使用的是机器系统提供的数据结构,在计算机底层有专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,效率较高。而堆的分配是由C/C++函数库提供的,有一定的分配算法,为了分配成功,会去搜索可用的足够大小的空间,还有可能引发用户态和内核态的切换,效率较低。

    3、正确使用内存

    从上面介绍的几个方面可以看出,栈高效,堆灵活,具体如何使用需要根据实际情况而定,不过使用不当的话很有可能引发系统错误,下面简单总结一下常见的情况。

    错误1:内存分配未成功,却使用了这个分配结果。
    正确1: 内存分配是有可能失败的,在使用之前一定要检查分配结果是否不为NULL。

    错误2:内存分配成功了,但是没有进行初始化就使用它。
    正确2:内存分配成功后,虽然一些简单数据类型的变量为0,但复杂结构的变量就不确定了,所以一定要进行初始化。

    错误3:内存越界。
    正确3:内存越界常发生在数组、容器的使用中,使用前一定要确认其索引/下标有效。

    错误4:没有释放已分配内存,造成内存泄漏。
    正确4:分配了内存之后忘记释放内存是可能发生的,造成内存泄漏,如果内存泄漏严重,就会造成内存不足或内存耗尽,所以malloc/free、new/delete一定要配对使用。

    错误5:函数返回了指向局部变量的指针或引用。
    正确5:局部变量使用的是栈内存,函数返回时局部变量的内存被自动释放,这时再通过指针或引用来使用这个变量的话就出错了,所以返回指向局部变量的指针或引用是禁止的,如果返回值为指针或引用的话,可以返回静态变量或全局变量,或者返回堆上的变量。

    错误6:误用野指针。
    正确6:用free或delete释放了内存后,还继续使用这块内存,这是有问题的,在内存释放后一定要把指针设置为NULL,避免野指针。

    4、关于double free

    当C++类中定义了指针成员变量,使用的却是默认拷贝构造函数时,是有可能发生常见的double free问题的,具体可参考:
    http://blog.csdn.net/ieearth/article/details/49332709

    5、内存检测

    Valgrind是一个内存检测工具,可以用来检测内存非法访问、内存泄漏等问题,具体可参考:
    http://blog.csdn.net/ieearth/article/details/48377493

    展开全文
  • 一种内存非法访问C++警示录一】

    千次阅读 2009-12-24 17:25:00
    的时候内存非法访问 这是什么原因?仍未解决,跪求原因     //用到的函数 void DealStrWitht(char *str) {  char *s=str;  char *addstr="/t";  while(*s != ' ' && *s != '/0')  {  s++;  }...

     char s[200];
     char strdeal[200];
     char area[10];
     char name[100];
     int i=0;
     ifstream ifs("C://Documents and Settings//Administrator//桌面//work//处理样本//产业园区.txt",ios_base::binary);
     ofstream ofs("C://Documents and Settings//Administrator//桌面//work//输出样本//产业园区deal.txt",ios_base::binary);
     while(ifs.good())
     {
      
      ifs.getline(s,200,'/n');
      DealStrWitht(s);
      
      if(!IsContains(s,"7天")&&(IsContains(s,"类别")||IsContains(s,"/"")||IsContains(s,"一篇")||IsContainsNumber(s)))
       continue;
      cout<<s<<endl;
      if(i%2 == 0)
      {
       if(Isblank(s))
       {
        i--;
        continue;
       }
       strcpy(strdeal,s);
      }
      else
      {
       if(Isblank(s))
       {
        i++;
        continue;
       }
    //   char area[10];//定义在这里面会出错
    //   char name[100];//
       strcpy(name,strdeal);
       GetArea(s,area);
       strcpy(strdeal,area);
       strcat(strdeal,name);
       strcat(strdeal,"/t");
       strcat(strdeal,s);
       strcat(strdeal,"产业园区/n");
       
       ofs.write(strdeal,strlen(strdeal));
      }
      i++;
      assert(s);
     }
     ifs.close();
     ofs.close();

     

     

     

    注释的那两行,如果这两个在这里定义的话就会ofs.write(strdeal,strlen(strdeal));
    的时候内存非法访问

    这是什么原因?仍未解决,跪求原因

     

     

    //用到的函数

    void DealStrWitht(char *str)
    {
     char *s=str;
     char *addstr="/t";
     while(*s != ' ' && *s != '/0')
     {
      s++;
     }
     *s++='/t';
     *s='/0'; 
    }

    void GetArea(char *strSource,char *area)
    {
     char *ss=strSource;
     char *sa=area;
     char *scity="市";
     bool findcity=false;
     int i=0;
     while(*ss != '/0')
     {
      if(*ss == *scity && *(ss+1) == *(scity+1))
      {
       findcity=true;
       ss++;
       ss++;
       strcpy(sa,ss);
       *(sa+6)='/0';
       strcat(sa,"/t");
       break;
      }
      ss++;
     }
    }

    bool IsContains(char *strSource,char *strDec)
    {
     char *ss=strSource;
     char *sd=strDec;
     while(*ss!='/0')
     {
      if(*ss == *sd)
      {
       char *sstemp=ss;
       while(*sd != '/0' && *sstemp == *sd)
       {
        sd++;
        sstemp++;
       }
       if(*sd =='/0')return true;
      }
      ss++;
     }
     return false;
    }
    bool IsContainsNumber(const char *strSource)
    {
     if(*strSource <= '9' && *strSource >='0')return true;
     if(*strSource == '一')return true;
     return false;
    }

    bool Isblank(char *strSource)
    {
     char *ss=strSource;
     if(*ss == '/n')return true;
     while(*ss !='/0'&& *ss++ ==' ')
     {
      
     }
     if(*ss-- == '/0')return true;
     if(*ss == '/n')return true;
     return false;
    }

    展开全文
  • C++程序内存布局

    千次阅读 2012-03-09 13:55:34
    C++程序内存布局探讨(一) 刘昕 重庆大学软件学院 摘要: 本文探讨了C++程序内存布局的基础知识,对堆、栈、全局数据区和代码区的概念进行了简单介绍,并介绍了内存对齐和进程地址空间(虚拟内存)方面的知识。 ...
  • C++内存

    千次阅读 2013-09-04 17:26:56
     在C/C++程序中,有关内存使用的问题是最难发现和解决的。这些问题可能导致程序莫名其妙地停止、崩溃,或者不断消耗内存直至资源耗尽。由于C/C++语言本身的特质和历史原因,程序员使用内存需要注意的事项较多,而且...
  • 知道c++中的变量存储方式,但是最近在思考一个问题,c++中的函数是怎样存储的,所以在网上找了一些资料,做了个总结,本文主要谈一谈C++程序内存的各个分配的内存区域以及各个内存区域之间的区别。 一、 内存的基本...
  • 关于C++内存管理

    千次阅读 2013-11-28 10:14:51
    内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不在,内存泄漏几乎在每个C++...
  • c++关于越界访问(内存溢出)

    千次阅读 2014-11-13 09:26:42
    越界访问访问了不是程序申请的内存区域
  • c++内存机制

    千次阅读 2017-09-13 21:23:22
    内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不在,内存泄漏几乎在每个C++...
  • C++内存管理

    千次阅读 2015-11-16 16:20:50
    内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不在,内存泄漏几乎在每个C++...
  • C++内存

    2019-01-08 02:09:47
    2、模拟踩内存,让程序崩溃。代码如下:int main(int argc, char* argv[]){ int a = 263; int* pa = &amp;a; char tmp[4]="ab"; strcpy(tmp,"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...
  • C++对象内存分配问题

    千次阅读 2016-10-18 22:14:26
    用C或C++写程序,需要更多地关注内存,这不仅仅是因为内存的分配是否合理直接影响着程序的效率和性能,更为主要的是,当我们操作内存的时候一不小心就会出现问题,而且很多时候,这些问题都是不易发觉的,比如内存...
  • 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对 C++的痛恨,但内存管理在C++中无处不在,内存泄漏几乎在每个C++...
  • c++ 程序内存布局

    2019-06-03 16:12:11
    转     对任何一个普通C++程序来讲,它都会涉及到5种不同的数据段。常用的几个数据段种包含有“程序代码段”、“程序数据段”、“程序堆栈段”等。...下面我们来简单归纳一下进程对应的内存空间...
  • 这几天遇到一个诡异的问题,关于C#调用 C++dll... 调用方法的时候, 都提示_ledHandle 非法访问内存。 然而 把_ledHandle 定义为局部变量的时候,是OK的。 很奇怪,百思不得其解............... ...
  • 内存管理、内存泄漏、内存回收探讨C++内存管理 分类: C++ 原文地址:http://www.cr173.com/html/18898_all.html 文章很棒,忍不住转载了 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议...
  • C++内存管理机制

    千次阅读 2014-08-27 17:05:45
    内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不在,内存泄漏几乎在每个C++...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 34,740
精华内容 13,896
关键字:

c++非法内存访问

c++ 订阅