Динамические матрицы и иже с ними
От: S10  
Дата: 08.12.08 22:29
Оценка: 19 (1)
Пишу лабу по динамическим массивам, сделал библиотеку:
using namespace std;
/* Создание матрицы. */
int **new_matrix (int height, int width)
{
    int **mx = new int *[height];
    for (int i = 0; i < height; i ++)
        mx[i] = new int[width];
    return mx;
}
/* Тотальный дестрой матрицы ^_^ */
void del_matrix (int **mx, int height)
{
    for (int i = 0; i < height; i++)
        delete mx[i];
    delete[] mx;
}
/* Заполнение матрицы случайным образом. */
void fill_matrix (int **mx, int height, int width)
{
    for (int i = 0; i < height; i ++)
        for (int j = 0; j < width; j ++)
            mx[i][j] = rand () % 151 - 50;
}
/* Заполнение матрицы нулями. */
void null_matrix (int **mx, int height, int width)
{
    for (int i = 0; i < height; i ++)
        for (int j = 0; j < width; j ++)
            mx[i][j] = 0;
}
/* Распечатка матрицы. */
void print_matrix (int **mx, int height, int width)
{
    cout << endl;
    cout << "Матрица:" << endl;
    for (int i = 0; i < height; i ++)
    {
        for (int j = 0; j < width; j ++)
            cout << mx[i][j] << "\t";
        cout << endl;
    }
    cout << endl;
}
/* Поиск числа а в матрице*/
int find_in_matrix (int **mx, int height, int width, int a)
{
    for (int i = 0; i < height; i ++)
        for (int j = 0; j < width; j ++)
            if (mx[i][j] == a)
                return i;
    return -1;
}
/* Вставка последней строки после строки с индексом n. */
void insert_last_after_n (int **mx, int &height, int width, int n)
{
    int **tmp = new_matrix (height + 1, width);
    /*null_matrix (tmp, height + 1, width);*/
    for (int i = 0; i <= n; i ++)
        for (int j = 0; j < width; j ++)
            tmp[i][j] = mx[i][j];
    n ++;
    int last = height - 1;
    for (int j = 0; j < width; j ++)
        tmp[n][j] = mx[last][j];
    if (n == height)
    {
        height ++;
        return;
    }
    for (int i = n + 1; i <= height; i ++)
        for (int j = 0; j < width; j ++)
            tmp[i][j] = mx[i - 1][j];
    del_matrix (mx, height);
    mx = tmp;
    height ++;
}


А вот собственно сама программа с заданием:
/* Вставить после строки, в которой есть заданное число А,
последнюю строку. */
#include "stdafx.h"
#include <iostream>
#include <ctime>
#include "..\matrix.h"
using namespace std;
int main ()
{
    setlocale (LC_ALL, "russian");
    srand ((unsigned) time (0));
    int a, m, n, index;
    do
    {
        cout << "Введите размерность матрицы (высота, ширина): ";
        cin >> m >> n;
    }
    while ((m <= 0) || (n <= 0));
    int **matrix = new_matrix (m, n);
    fill_matrix (matrix, m, n);
    print_matrix (matrix, m, n);
    cout << "Введите число для поиска: ";
    cin >> a;
    index = find_in_matrix (matrix, m, n, a);
    if (index < 0)
    {
        cout << "Число не было найдено в матрице" << endl;
        system ("pause");
        exit (1);
    }
    insert_last_after_n (matrix, m, n, index);
    print_matrix (matrix, m, n);
    del_matrix (matrix, m);
    system ("pause");
    return 0;
}


Проблема: комплится, вставка последней строки после строки с индексом n вроде работает под отладчиком, но при распечатке результирующей матрицы всё валится В чём мои ошибки?
Re: Динамические матрицы и иже с ними
От: Кодт Россия  
Дата: 08.12.08 23:30
Оценка: 38 (1)
Здравствуйте, S10, Вы писали:

S10>Пишу лабу по динамическим массивам, сделал библиотеку:

S10>

S10>/* Вставка последней строки после строки с индексом n. */
S10>void insert_last_after_n (int **mx, int &height, int width, int n)
S10>{
S10>    int **tmp = new_matrix (height + 1, width);
.............................
S10>    del_matrix (mx, height);
S10>    mx = tmp;
S10>    height ++;
S10>}
S10>


S10>А вот собственно сама программа с заданием:

S10>
S10>    int **matrix = new_matrix (m, n);
..............................
S10>    insert_last_after_n (matrix, m, n, index);
S10>    print_matrix (matrix, m, n);
S10>    del_matrix (matrix, m);
S10>


Ошибка в том, что insert_last_after_n уничтожает исходную матрицу, не сообщая об этом наружу. Заодно у тебя получилась утечка, но ты её не успел заметить
Нужно поменять сигнатуру этой функции
S10>void insert_last_after_n (int ** /*inout*/ & mx, int /*inout*/ & height, int width, int n)


Кстати говоря. Поскольку размеры матрицы ходят парой вместе с ею самой, то было бы логично объединить их в одну структуру
struct matrix
{
  int width, height;
  int** data;
};

matrix new_matrix(int w, int h);
void delete_matrix(matrix m); // здесь спокойно можно по значению - копирование поверхностное
void insert_row(matrix& m, int jInsertTo, int jCopyFrom)
{
  matrix mx = new_matrix(m.width, m.height+1);
  for(int i=0; i!=mx.width; ++i)
  {
    for(int j=0; j!=mx.height; ++j)
    {
      int jSrc = (j<jInsertTo) ? j : (j==jInsertTo) ? jCopyFrom : (j+1);
      mx[i][j] = m[i][jSrc];
    }
  }
}
Перекуём баги на фичи!
Re: Динамические матрицы и иже с ними
От: Arsenicum Россия  
Дата: 09.12.08 10:22
Оценка:
Мои пять копеек:

S10>...
S10>/* Тотальный дестрой матрицы ^_^ */
S10>void del_matrix (int **mx, int height)
S10>{
S10>    for (int i = 0; i < height; i++)
S10>        delete[] mx[i];
S10>    delete[] mx;
S10>}
S10>...
Re[2]: Динамические матрицы и иже с ними
От: S10  
Дата: 09.12.08 14:06
Оценка:
Здравствуйте, Кодт, Вы писали:
К>Кстати говоря. Поскольку размеры матрицы ходят парой вместе с ею самой, то было бы логично объединить их в одну структуру
Ещё логичнее было бы написать класс для матрицы, но пока лениво, реализую структурой, спасибо за замечание
Спасибо за советы, счас буду пробовать.
Re[2]: Динамические матрицы и иже с ними
От: S10  
Дата: 09.12.08 14:10
Оценка:
Здравствуйте, Arsenicum, Вы писали:
A>
    delete[] mx[i];
A>


В прошлом семестре при написании примера класса динамического массива преподаватель использовал именно delete, а не delete[]. Есть ли принципиальная разница?
Re[3]: Динамические матрицы и иже с ними
От: Кодт Россия  
Дата: 09.12.08 14:37
Оценка:
Здравствуйте, S10, Вы писали:

S10>В прошлом семестре при написании примера класса динамического массива преподаватель использовал именно delete, а не delete[]. Есть ли принципиальная разница?


Возможно, он хотел завалить вас на экзамене
Принципиальная разница записана в Стандарте языка С++. Использование непарных выражений (delete new T[N]), (delete[] new T()) — неопределённое поведение.
Потому что:
— могут использоваться разные кучи для массива и для одиночного объекта
— могут по-разному определяться размеры блоков
— неадекватно отработают деструкторы (если они нетривиальные)
и прочая, и прочая...
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.