为什么我在使用malloc()时遇到运行时错误

时间:2016-09-29 18:13:23

标签: c++ arrays c++11 dynamic

我有时会遇到运行时错误,有时我的程序会触发断点。以下程序从用户的值中获取值,并创建该大小的动态数组。如果用户继续输入添加数据选项,则数组的大小加倍,并允许用户添加更多数据。现在,如果我将动态数组的大小输入为1,则在接近11个条目后,我会收到运行时错误,或者有时程序也会触发断点。是什么原因

#include <iostream>
#include <Windows.h>
using namespace std;
int main() {
    int size = 0;
    cout << "Please Input The Size of Your List: ";
    cin >> size;
    int curremt = 0;
    int in_check = 0;
    int del_check = 0;
    int * list;
    list = (int*)malloc(size);
    char choice = ' ';
    while (choice != 'E'|| choice != 'e') {
        system("cls");
        cout << "Press 1 to Add data"<<endl;
        //cout << "Press 2 to Delete data" << endl;
        cout << "Press 3 to  View data" << endl;
        cout << "Press E to Exit" << endl;
        cout << "Please Input Choice: ";
        cin >> choice;
        if (choice=='1') {
            in_check++;
            if (!(in_check>size))
            {
                cout << "Please Input Data: ";
                cin >> list[curremt];
                curremt++;
            }
            else {
                int * temp = new int[size];
                for (int i = 0; i < size; i++)
                {
                    temp[i] = list[i];
                }
                list = (int*)realloc(list, (size * 2));
                for (int i = 0; i < size; i++)
                {
                    list[i] = temp[i];
                }
                delete[] temp;
                size = size * 2;
                cout << "Please Input Data: ";
                cin >> list[curremt];
                curremt++;
                in_check = ((size/2)+1);
            }
        }
        else if (choice == '3') {
            for (int i = 0; i < curremt; i++)
            {
                cout << "Data At Position " << i << ":" << list[i]<<endl;
            }
            Sleep(500*size);
        }
        else if (choice == '2') {

        }
    }
    return 0;
}

我解决了我的问题这个问题实际上是realloc()和malloc()的错误使用 按照代码工作正常

#include <iostream>
#include <Windows.h>
using namespace std;
int main() {
    int size = 0;
    cout << "Please Input The Size of Your List: ";
    cin >> size;
    int curremt = 0;
    int in_check = 0;
    int del_check = 0;
    int * list;
    list = (int*)malloc(size*sizeof(int));
    char choice = ' ';
    while (choice != 'E'|| choice != 'e') {
        system("cls");
        cout << "Press 1 to Add data"<<endl;
        //cout << "Press 2 to Delete data" << endl;
        cout << "Press 3 to  View data" << endl;
        cout << "Press E to Exit" << endl;
        cout << "Please Input Choice: ";
        cin >> choice;
        if (choice=='1') {
            in_check++;
            if (!(in_check>size))
            {
                cout << "Please Input Data: ";
                cin >> list[curremt];
                curremt++;
            }
            else {
                int * temp = new int[size];
                for (int i = 0; i < size; i++)
                {
                    temp[i] = list[i];
                }
                list = (int*)malloc((size*2)*(sizeof(int)));
                for (int i = 0; i < size; i++)
                {
                    list[i] = temp[i];
                }
                delete[] temp;
                size = size * 2;
                cout << "Please Input Data: ";
                cin >> list[curremt];
                curremt++;
                in_check = ((size/2)+1);
            }
        }
        else if (choice == '3') {
            for (int i = 0; i < curremt; i++)
            {
                cout << "Data At Position " << i << ":" << list[i]<<endl;
            }
            Sleep(500*size);
        }
        else if (choice == '2') {
            cout << "Data at array position " << curremt << " deleted" << endl;
            curremt--;

        }
        else if (choice == 'e'||choice=='E') {
            exit(0);
        }
        else {
            cout << "Wrong Choice" << endl;
        }
    }
    return 0;
}

1 个答案:

答案 0 :(得分:0)

您以两种方式组织缓冲区溢出:

  • 首先,(int*)malloc(size)分配size个字节,所以size/sizeof(int)个整数,这比你预期的少了几个。例如,假设您的编译器使用4个字节的整数:如果size为5,则可以存储至少一个整数。
  • 然后循环,从用户获取数据,并将其存储在索引指针中。这很好,只要你不超过尺寸。不幸的是,在我们的示例中,您很快就会达到2和3,因此没有预留空间。所以你破坏了内存,这可能会迟早导致段错误或其他奇怪的行为。

此外,在C ++中,您应该避免使用malloc() / free()并使用newdelete。我想你已经这样做了,以便用realloc()简化表格的增长,但这不是一个好主意。

您可以使用 vector 重写整个内容。这样会更加安全和方便!

#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<int> list;  
    char choice = ' ';
    while (choice != 'E'|| choice != 'e') {
        system("cls");
        cout << "Press 1 to Add data"<<endl;
        ...
        cin >> choice;
        if (choice=='1') {
             int i; 
             cout << "Please Input Data: ";
             cin >> i;
             list.push_back(i);
        }
        else if (choice == '3') {
            for (int i = 0; i < list.size(); i++)
                cout << "Data At Position " << i << ":" << list[i]<<endl;
         }
        else if (choice == '2') {

        }
    }
}

修改

如果您不允许使用向量,并且如果您坚持使用realloc(),则还应将重新分配的大小乘以sizeof(int)。但实际上,在C ++中,我强烈反对保留它,并选择新/删除。

无论如何,如果需要,您不会利用realloc的功能移动内存块的内容。因此,不要将所有项目复制到temp并将其复制回list,而不是更容易这样做(假设代码中只有新/删除):

            int * temp = list;
            list = new int[size * 2];
            for (int i = 0; i < size; i++)
            {
                list[i] = temp[i];
            }
            delete[] temp;
            size = size*2;