动态地将内存分配给矩阵

时间:2019-02-20 00:34:57

标签: c++ matrix

我试图将数组转换为矩阵,所以我为矩阵动态分配了内存,但出现错误:

  

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

void add(Person * a, int * tam) {

    char name[30];
    int op = 0;
    int c, day = 0, month = 0, year = 0, Calendar = -1;
    float sal = -1;

    for (int i = 0; i < *tam + 1; i++)
    {
        printf("Insert your name:\n");
        fgets(name, 30, stdin);
        *a[i].name = name;

        while ((c = getchar()) != '\n' && c != EOF)
            ;
        do
        {
            printf("Insert %s's age:\n", name);
            scanf("%d", &op);
            while ((c = getchar()) != '\n' && c != EOF)
                ;
            if (!op)
                printf("invalid age!\n");
            else
                a[i].age = op;
        } while (op <= 0);
        do
        {
            printf("Insert %s's salary:\n", name);
            scanf("%f", &sal);
            while ((c = getchar()) != '\n' && c != EOF)
                ;
            if (sal < 0)
                printf("Invalid salary!\n");
            else
                a[i].salary = sal;

        } while (sal < 0);
        do
        {
            printf("Insert %s's date birth\n", name);
            printf("Day:\n");
            scanf("%d", &day);
            while ((c = getchar()) != '\n' && c != EOF)
                ;
            printf("Month:\n");
            scanf("%d", &month);
            while ((c = getchar()) != '\n' && c != EOF)
                ;
            printf("Year:\n");
            scanf("%d", &year);
            while ((c = getchar()) != '\n' && c != EOF)
                ;

            if ((day > 0 && day < 31) && (month > 0 && month < 12) && (year > 0))
            {
                Calendar = 1;
                a[i].birth.day = day;
                a[i].birth.month = month;
                a[i].birth.year = year;
            }
            else
                printf("Invalid calendar!\n");

        } while (Calendar != 1);

    }
    *tam++;
}

main() {
    Person book[10];
    int c, tam = 0;
    char op, out = 0;
    while (!out)
    {

        do
        {
            printf("1: Insert a profile\n");
            printf("2: Change a profile\n");
            printf("3: Erase a Profile\n");
            printf("4: Show all profiles\n");
            printf("5: Search\n");
            printf("0: Exit\n");
            scanf("%c", &op);
            while ((c = getchar()) != '\n' && c != EOF)
                ;

        } while (op < '0' || op > '5');

        switch (op)
        {
        case '1':
            add(book, &tam);
            break;
        case '2':

            break;
        case '3':

            break;
        case '4':
            read(book, &tam);
            break;
        case '5':

            break;
        case '0':
            out = 1;
            break;
        default:
            break;
        }

    }

}

2 个答案:

答案 0 :(得分:0)

您的代码有两个主要问题:

问题1:

float **A_mat = new float*[r]; // allocating memory for 2 rows because r = sqrt(9) - 1 => r = 2

for (int i = 0; i <= r; i++)
    A_mat[i] = new float[r]; // Usage of A_mat[r] for r = 2 is out of bounds. Also, memory is allocated for 2 columns.

问题2:

for (int j = 0; j <= r; j++) {
    for (int i = 0; i <= r; i++) {
        A_mat[j][i] = a[i + j * (r+1)]; // accessing indices (0, 2), (1, 2), (2, 0), (2, 1), (2, 2) are out of bounds
    }
}

相反,您应该分配(r + 1)个大小的内存。像这样:

int main() {

    float a[9] = { 1, 3, 5, 6,4,6,5,6,8};

    int b = sizeof(a)/sizeof(a[0]);
    int r = sqrt(b) - 1;

    float **A_mat = new float*[r + 1];
    //A_mat = ;

    for (int i = 0; i <= r; i++)
        A_mat[i] = new float[r + 1];

    for (int j = 0; j <= r; j++) {
        for (int i = 0; i <= r; i++) {
            A_mat[j][i] = a[i + j * (r+1)];
        }
    }

    cout << "a[0,0] is " << A_mat[0][0] << endl;
    cout << "a[0,2] is " << A_mat[0][2] << endl;
    cout << "a[1,0] is " << A_mat[1][0] << endl;
    cout << "a[2,0] is " << A_mat[2][0] << endl;

    for (int i = 0; i <= r; i++) {
        delete[] A_mat[i];
    }

    delete[] A_mat;

    system("pause");
}

建议

1)切勿使用原始指针。始终寻找更安全的选择。在这种情况下,您应该选择std::vector

2)切勿使用裸露的new。通常,它是内存泄漏的主要来源。尽管目前,对您而言并非如此。但这可能会成为将来的问题。

3)切记,数组从C ++的0索引开始。

答案 1 :(得分:0)

您对for循环有疑问。索引是从0到(r-1)。但是您的for循环从0到r。它超出了您的数组范围。

1>因此,请将其替换为循环

for (int i = 0; i <= r; i++)

通过

for (int i = 0; i < r; i++)

2>并替换此语句

for (int j = 0; j <= r; j++) {
    for (int i = 0; i <= r; i++) {
        A_mat[j][i] = a[i + j * (r+1)];
    }
}

作者

for (int j = 0; j < r; j++) {
    for (int i = 0; i < r; i++) {
        A_mat[j][i] = a[i + j * r];
    }
}