【问题标题】:HEAP CORRUPTION DETECTED: after Normal block (#153)检测到堆损坏:在正常块之后 (#153)
【发布时间】:2023-03-21 15:56:02
【问题描述】:

CRT 检测到应用程序在堆缓冲区结束后写入内存。

但我不确定我在哪里写了堆。一旦我调用 delete[] 数据就会发生错误;

Data 是一个指向双精度数组的指针。我试图去掉一些不必要的代码。

源代码:

#include "sequence2.h"
using namespace main_savitch_4;

// CONSTRUCTORS and DESTRUCTORS

// The default sequence constructor
// Purpose: To create an instance of a sequence
// Parameters: (int) initial_capacity
// Returns: None
sequence::sequence(int initial_capacity)
{
    // Allocate memory for the new sequence
    data = new value_type[capacity];
    // Set the capacity to the passed in capacity
    capacity = initial_capacity;
    // Set used to 0 because there are currently no objects in the sequence
    used = 0;
    // Set the current index to the 0 for the first item
    current_index = 0;
}

// The sequence copy constructor
// Purpose: To create a deep copy of a sequence
// Parameters: A source sequence
// Returns: None
sequence::sequence(const sequence& source)
{
    // Allocate memory to the new sequence using the capacity of the passed sequence
    data = new value_type[source.capacity];
    // Set the capacity to the passed capacity
    capacity = source.capacity;
    // Set used to the number of used indexes in the previous sequence
    used = source.used;
    // Set the current_index to the index of the passed sequence
    current_index = source.current_index;

    // Copy all data from the passed sequence into the new sequence
    for (int i = 0; i < used; i++)
    {
        data[i] = source.data[i];
    }
}

// The default sequence destructor
// Purpose: To de-allocate memory for a sequence
// Parameters: None
// Returns: None
sequence::~sequence()
{
    // De-allocate dynamic memory
    delete[] data;
}

// MODIFICATION MEMBER FUNCTIONS

// The overload assignment operator function
// Purpose: To assign a sequence with the data from another sequence
// Parameters: A source sequence
// Returns: None
void sequence::operator=(const sequence& source)
{
    value_type *new_data;

    // Check for possible self-assignment
    if (this == &source)
        return;

    // If the capacity of the source is not equal to the original
    if (capacity != source.capacity)
    {
        // Create a new sequence using the source capacity
        new_data = new value_type[source.capacity];
        // Delete the old sequence
        delete[] data;
        // Assign data pointer to the new sequence
        data = new_data;
        // Set capacity to the new source capacity
        capacity = source.capacity;
    }

    // Set used equal to the source "used"
    used = source.used;

    // Copy data from the source sequence into the new sequence
    for (int i = 0; i < used; i++)
    {
        data[i] = source.data[i];
    }
}

// The resize function
// Purpose: To grow a sequence when necessary
// Parameters: (int) new_capacity
// Returns: None
void sequence::resize(int new_capacity)
{
    // Declare a larger array
    value_type *larger_array;

    if (new_capacity == capacity)
        return; // The allocated memory is already the right size

    if (new_capacity < used)
        new_capacity = used; // Can't allocate less than we are using

    // Dynamically allocate memory for the larger array with the new capacity
    larger_array = new value_type[new_capacity];

    // Copy the data from the old array to the larger array
    for (int i = 0; i < used; i++)
    {
        larger_array[i] = data[i];
    }
    // Delete the old array
    delete[] data;
    // Set the pointer to the larger array
    data = larger_array;
    // Set the capacity to the new capacity
    capacity = new_capacity;
}

// The insert function
// Purpose: To insert an item before the current index
// Parameters: (const value_type&) entry
// Returns: None
void sequence::insert(const value_type& entry)
{
    // If used and capacity are the same, resize the sequence
    if (used == capacity)
        resize(used + 1);

    // If the current index is an item...
    if (is_item())
    {
        // Block of code that moves objects ahead of insert forward
        for (int i = used; i > current_index; i--)
        {
            data[i] = data[i-1];
        }
    }

    // Set the current index to the new entry
    data[current_index] = entry;
    // Increment used because we've added an item
    ++used;
}

// The attach function
// Purpose: To attach an item after the current index
// Parameters: (const value_type&) entry
// Returns: None
void sequence::attach(const value_type& entry)
{
    // If used and capacity are the same, resize the sequence
    if (used == capacity)
        resize(used + 1);

    // If the current index is an item...
    if (is_item())
    {
        // Block of code that moves objects ahead of attach forward
        for (int i = used; i > current_index; i--)
        {
            data[i] = data[i-1];
        }

        // Set the current index to the recently attached item
        ++current_index;
        // Store the entry in the new current index
        data[current_index] = entry;
    }
    else
    {
        // Set the current index to the end of the sequence
        current_index = used;
        // Put that entry into that new index
        data[current_index] = entry;
    }

    // Increment used because we've added an item
    ++used;
}

// CONSTANT MEMBER FUNCTIONS

// The is_item function
// Purpose: To check if the current index contains an item
// Parameters: None
// Returns: None
bool sequence::is_item() const
{
    // If the current index is greater than used, or used is equal to 0
    // there is no current item
    if (current_index >= used || used == 0)
        return false;
    else // otherwise there is a current item
        return true;
}

【问题讨论】:

  • 对于初学者,在复制赋值运算符中,您不会复制 current_index 成员变量。这可能是您的问题的一部分吗?
  • 我应该澄清一下,当我将数据写入 inset 和 attach 函数中的动态序列时,我认为问题存在。
  • 另外,尝试创建最短和最简单的导致您的问题的示例,然后使用调试器逐行逐行检查代码,看看它不会在任何地方超出范围。跨度>
  • @ColinMarshall 解决此类问题的正确工具是您的调试器。 询问 Stack Overflow 之前,您应该逐行逐行检查您的代码。如需更多帮助,请阅读How to debug small programs (by Eric Lippert)。至少,您应该 [编辑] 您的问题,以包含一个重现您的问题的 Minimal, Complete, and Verifiable 示例,以及您在调试器中所做的观察。

标签: c++ pointers memory heap-memory


【解决方案1】:

大声笑,这是解决方案

sequence::sequence(int initial_capacity)
{
    // Allocate memory for the new sequence
    data = new value_type[**initial_capacity**];
    // Set the capacity to the passed in capacity
    capacity = initial_capacity;
    // Set used to 0 because there are currently no objects in the sequence
    used = 0;
    // Set the current index to the 0 for the first item
    current_index = 0;

}

【讨论】:

  • 一个好的编译器,可能启用了额外的警告,能够告诉你何时使用未初始化的变量。
猜你喜欢
  • 2013-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-10
  • 1970-01-01
  • 1970-01-01
  • 2011-07-24
相关资源
最近更新 更多