为什么我有动态内存分配(堆)的运行时错误?

时间:2012-03-19 11:43:23

标签: c++ function memory memory-management heap

每次我取消注释l70-72时,我的程序都会遇到运行时错误。这不是我第一次遇到这个特殊问题。

我创建一个指向对象数组的指针,将该指针发送到一个函数中,尝试在main中执行该函数中定义的命令并获得运行时错误,所有这些都在使用堆时。这个指针或数组中的指针显然会发生一些事情。

当我使用以下任何一项呼叫manage_Rectangle_arr(string strCommand, Rectangle * *arr, short *siArrayL)时发生错误:"填充数组","获取区域"和#34;空内容" (显然最后两个与"填充数组"本质上是相关的,因为它们需要先执行才能运行)

void manage_Rectangle_arr(string, Rectangle * *, short*);

int main()
{
    Rectangle * * arr;
    short siArrayL=1;

    manage_Rectangle_arr("make array", arr, &siArrayL);
    manage_Rectangle_arr("fill array", arr, &siArrayL); //Problem here
    manage_Rectangle_arr("get areas", arr, &siArrayL); //Problem here
    manage_Rectangle_arr("empty contents", arr, &siArrayL); //Problem here
    manage_Rectangle_arr("delete array", arr, &siArrayL);
}

void manage_Rectangle_arr(string strCommand, Rectangle * *arr, short *siArrayL)
{
    if(strCommand=="make array")
    arr = new Rectangle * [ *siArrayL];

    if(strCommand=="fill array") //Problem here
    for(short s=0; s< *siArrayL; ++s)
    arr[s]= new Rectangle(1, 1);

    if(strCommand=="get areas") //Problem here
    for(short s=0; s< *siArrayL; ++s)
    cout << arr[s]->getArea();

    if(strCommand=="empty contents") //Problem here
    for(short s=0; s< *siArrayL; ++s)
    delete arr[s];

    if(strCommand=="delete array")
    delete [] arr;
}

//When I call manage_Rectangle_arr(string strCommand, Rectangle * *arr, short *siArrayL) with any of the following: "fill array", "get areas" and "empty contents" (obviously the last two are related to "fill array" in nature, since they need it to be executed first in order to function)

Full C++ Source Code

2 个答案:

答案 0 :(得分:3)

从根本上说,除了Max指出的按值调用问题外,此代码还有两个问题。

第一个错误是您没有正确使用函数,并且滥用字符串来发出命令。

第二个错误是you are using pointers。每个C ++课程都会出错。指针在大多数C ++代码中都没有位置。不要养成坏习惯。

更正并简化,代码应如下所示:

int main()
{
    short siArrayL=1;
    std::vector<Rectangle> arr(siArrayL);

    fill_array(arr);
    print_areas(arr);
}

使用两种方法:

void fill_array(std::vector<Rectangle>& arr) {
    for (std::vector<Rectangle>::iterator i = arr.begin(); i != arr.end(); ++i)
        *i = Rectangle(1, 1);
}

void print_areas(std::vector<Rectangle> const& arr) {
    for (std::vector<Rectangle>::const_iterator i = arr.begin(); i != arr.end(); ++i)
        std::cout << i->getArea();
}

特别注意如何不再使用“空内容”和“删除数组”。不使用指针只有两个好处。

答案 1 :(得分:1)

即使这似乎有很多挫折,但我会尽力提供一个有用的答案。 :)

您的数组类型为Rectangle** - 即指向矩形指针的指针。您可以通过值将其发送到方法中。这意味着原始方法中arr的值将被复制到arr中的变量manage_Rectangle_arr中。因此,当您为arr赋值{(new内存区/数组的地址)arr时,只会在被调用函数中包含此值 - 因为这些是完全不同的变量。 / p>

如果您将manage_Rectangle_arr声明为

void manage_Rectangle_arr(string strCommand, Rectangle * * &arr, short *siArrayL)

该变量/内存区域将通过引用发送,这意味着它将是另一个自动的间接级别。您可以通过使用Rectangle ***类型的变量并取消引用变量arr来实现此目的,但这很快就会变得愚蠢。

您的代码中还有许多其他“非最佳实践”,但我不会在这里谈论它们。 :)希望这会帮助你重回正轨!