【问题标题】:_CrtlIsValidHeapPointer error during destruction_CrtlIsValidHeapPointer 销毁时出错
【发布时间】:2018-05-24 10:01:19
【问题描述】:

当我的显示对象 t_display 被解构时,我收到了 _CrtlIsValidHeapPointer(block) 错误。这发生在 Animation.cpp 中的 while 循环之后,用于获取用户输入并进行多次显示。

我知道这是因为我为char * p_name 分配了内存,并将该指针存储在对象中,但我不知道如何解决它。我必须使用 char * 作为显示对象名称,这意味着我必须为它分配内存。

我认为可能是两个问题之一。 1) 我为 char * 分配了错误的内存,或者错误地复制了字符串 2)我把析构函数写错了

在这两种情况下,我都不确定如何解决我遇到的这个错误,希望你能指出我正确的方向。

动画.cpp

#include <crtdbg.h>
#include <iostream>
#include <string>
#include <vector>
#include <forward_list>
using namespace std;

#include "Display.h"
#include "Frame.h"
#include "Animation.h"


void Animation::InsertFrame() {

    int numDisplays; //for user input of display number
    vector <Display>v; //vector for containing display objects
    int p_x; //will contain user input for pixel_x
    int p_y; //will contain user input for pixel_y
    int p_duration; //will contain user input for duration
    char * p_name; //temp string to contain user input for name

   //will contain p_name to be passed to display constructor
    string frameName; //contains user input for the frame name
    int q = 0; //used to count the diplay #

    //begin reading user input
    cout << "Insert a Frame in the Animation\nPlease enter the Frame filename: " ;
    cin >> frameName;
    cout << "Entering the Frame Displays (the sets of dimensions and durations) " << endl;
    cout << "Please enter the number of Displays: " ;
    cin >> numDisplays;
    string d_name;

    //display creation loop for # of displays entered
    while (numDisplays > 0) {
        //char * name=nullptr;
        cout << "Please enter pixel x for Display #"<<q<<" pixel_x:";
        cin >> p_x;
        cout << "Please enter pixel y for Display #"<<q<<" pixel_y:" ;
        cin >> p_y;
        cout << "Please enter the duration sec for this Display: " ;
        cin >> p_duration;
        cout << "Please enter the name for this Display: " ;
        //cin >> p_name;
        cin >> d_name;
        //p_name = new char[strlen(name)];
        p_name = new char[d_name.length() + 1]; //allocate for the size of the name entered
        strcpy(p_name, d_name.c_str()); //copy string to char []
        Display t_display =  Display(p_x, p_y, p_duration, p_name); //make a new display with the user input values
        v.push_back(t_display); //pushing onto the vector
        numDisplays--;
        q++;

    }

显示.h

// Display.h
#pragma once

class Display
{
    int pixel_x;
    int pixel_y;
    int duration;
    char* name;
public:
    Display(int x, int y, int duration, char* name);
    Display(const Display&);
    ~Display();
    friend ostream& operator<<(ostream&, Display&);
};

显示.cpp

#include <crtdbg.h>
#include <iostream>
#include <string>
#include <vector>
#include <forward_list>
using namespace std;
#include "Display.h"

Display::Display(int x, int y, int d, char* n):pixel_x(x), pixel_y(y), duration(d), name(n) {
}
Display::Display(const Display& p) {
    //copy values from p
    pixel_x = p.pixel_x;
    pixel_y = p.pixel_y;
    duration = p.duration;
    name = p.name;

}
Display::~Display() {

}

该程序在没有析构函数的情况下工作,但当然存在内存泄漏,这是不可接受的。当我添加一个简单的析构函数时,例如:

if(name){
 delete[] name;
}

它会抛出那个错误。

【问题讨论】:

    标签: c++ string memory-leaks char destructor


    【解决方案1】:

    在您的 copy-ctor 中,您将 name 的值分配给新对象,因此 dtor 将为原始对象和复制对象运行,但每个对象都将尝试释放指针。

    在您的 ctor 中分​​配一个新缓冲区并复制内容。更好的是简单地使用 std::string 作为 Display 成员,那么您需要关心的唯一缓冲区就是您用来查询操作系统的缓冲区。

    【讨论】:

    • 当您说分配一个新缓冲区并复制内容时,您到底是什么意思? c++ 对我来说相当新,我不确定缓冲区是什么。这是 char 数组的另一个名称吗?
    • 我的意思是在你的copy-ctor中有: size_t len = strlen(p.name);名称 = 新字符 [len + 1]; strcpy(名称,p.name);这样做,副本和原始将具有不同的缓冲区(请注意,可能仍然存在问题,因为您没有显示您传递给原始 Display 对象的 ctor 的内容)。就像我说的,使用 std::string 作为成员类型会好得多。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-06
    • 2011-09-26
    • 1970-01-01
    • 2012-08-21
    • 1970-01-01
    • 2016-12-06
    • 2022-01-03
    相关资源
    最近更新 更多