Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Неправильно обрабатываются массивы, Undefined behavior? 
:(
    Опции темы
efpies
Дата 15.2.2012, 04:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 20.6.2009
Где: СПб

Репутация: нет
Всего: нет



Я уже конкретно ничего не понимаю. Не понимаю, что вообще происходит.

Есть 2 объекта (координаты хранятся в массивах double**):
a = [10, 50, 1];
b = [10, 150, 1];

Есть матрица сдвига
1 0 0
0 1 0
50 0 1

Есть такая вот функция:
Код

void CustomPoint::applyTransform (Matrix* transform)
{
    Matrix temp = *coords * *transform;
    delete coords;
    coords = new Matrix(temp);
}

Чем она примечательна? Если оставить вот так, то b будет с неверными координатами (не [60 150 1], а [60 200 2]). Но если сразу же после последнего присваивания пройтись циклом с обращением к элементам или написать
Код

coords->values[0][0] = 5; // Установить элемент матрицы [0,0] = 5

то совершенно невероятным образом b будет [60 150 1]

То же самое будет, если убрать вторую строчку функции.

Что это?

Это сообщение отредактировал(а) efpies - 15.2.2012, 04:42
PM MAIL   Вверх
borisbn
Дата 15.2.2012, 09:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Абсолютно верно утверждают, что современная цивилизация утеряла способности телепатии, поэтому без знания, что такое Matrix ответить немного проблематично


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
efpies
Дата 15.2.2012, 12:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 20.6.2009
Где: СПб

Репутация: нет
Всего: нет



Я считаю, что это лишнее в данном треде.
Но коли так, приведу

Matrix.h
Код

//---------------------------------------------------------------------------
#ifndef MatrixH
#define MatrixH

class Matrix {
    protected :
        unsigned rows;
        unsigned cols;

        void alloc();
        void dealloc();

    public :
        Matrix (unsigned, unsigned);
        Matrix (const Matrix&);
        ~Matrix();

        Matrix& operator=  (const Matrix&);
        Matrix& operator*= (const Matrix&);
 friend Matrix  operator*  (const Matrix&, const Matrix&);
        double  **values;
};
//---------------------------------------------------------------------------
#endif


Matrix.cpp
Код

//---------------------------------------------------------------------------
#pragma hdrstop

#include "Matrix.h"
#include "Helpers.h"

using namespace std;
//---------------------------------------------------------------------------
#pragma package(smart_init)

Matrix::Matrix (unsigned r, unsigned c) : rows(r), cols(c)
{
    alloc();
}

Matrix::Matrix(const Matrix& src)
{
    rows = src.rows;
    cols = src.cols;
    alloc();

    for (unsigned i = 0; i < rows; i++) {
        for (unsigned j = 0; j < cols; j++) {
            values[i][j] = src.values[i][j];
        }
    }
}

Matrix::~Matrix()
{
    dealloc();
}

void Matrix::alloc()
{
    values = new double*[rows];

    for (unsigned i = 0; i < rows; ++i) {
        values[i] = new double[cols];
    }
}

void Matrix::dealloc()
{
    for (unsigned i = 0; i < rows; ++i) {
        delete [] values[i];
    }

    delete [] values;

    values = NULL;
    rows = cols = 0;
}

Matrix& Matrix::operator=(const Matrix& right)
{
    if (&right != this)
    {
        dealloc();
        rows = right.rows;
        cols = right.cols;

        if(rows && cols)
        {
            values = new double*[rows];

            for (unsigned i = 0; i < rows; ++i)
                values[i] = new double[cols];

            for (unsigned i = 0; i < rows; ++i)
                for (unsigned j = 0; j < cols; ++j)
                    values[i][j] = right.values[i][j];
        }
    }

    return *this;
}


Matrix operator* (const Matrix& left, const Matrix& right)
{
    Matrix result(left);
    return result *= right;
}

Matrix& Matrix::operator*=(const Matrix& right)
{
    if (cols == right.rows)
    {
        Matrix temp(rows, right.cols);

        for (unsigned i = 0; i < temp.rows; ++i)
            for (unsigned j = 0; j < right.cols; ++j)
                for (unsigned k = 0; k < right.rows; ++k)
                    temp.values[i][j] += values[i][k] * right.values[k][j];

        dealloc();

        rows = temp.rows;
        cols = temp.cols;

        if(rows && cols)
        {
            values = new double*[rows];

            for (unsigned i = 0; i < rows; ++i)
                values[i] = new double[cols];

            for (unsigned i = 0; i < rows; ++i)
                for (unsigned j = 0; j < cols; ++j)
                    values[i][j] = temp.values[i][j];
        }
    }

    return *this;
}

PM MAIL   Вверх
borisbn
Дата 15.2.2012, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



кроме того, что ты нигде не обнуляешь матрицу, однако делаешь
Цитата(efpies @  15.2.2012,  12:39 Найти цитируемый пост)
temp.values[i][j] += values[i][k] * right.values[k][j];

проблем не увидел.
я тебе подготовил шаблончик для проверки. 
http://liveworkspace.org/code/f013f3501db9...516087019ba88dc
добавь туда недостающий код, генерирующий проблему и выложи ссылку сюда.
Если же ошибка не повторится, то проблема в каком-то другом месте, а не в том, которое ты привёл


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
efpies
Дата 15.2.2012, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 20.6.2009
Где: СПб

Репутация: нет
Всего: нет



http://liveworkspace.org/code/03630dd3e135...15a4f060587963b

в общем-то, обнуление помогло. спасибо smile
PM MAIL   Вверх
borisbn
Дата 15.2.2012, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



ну и хорошо. а что за мазохизм с сырыми указателями ??? почему не vector ?


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
borisbn
Дата 15.2.2012, 18:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



вот сравни
http://liveworkspace.org/code/c2e9db20f10e...2da5f3c7c3501b3
в твоём классе Matrix 126 строк, а в том, который с vector'ами - 47  smile 

Это сообщение отредактировал(а) borisbn - 15.2.2012, 18:46


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
efpies
Дата 15.2.2012, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 20.6.2009
Где: СПб

Репутация: нет
Всего: нет



vector - это хорошо, но пока что передо мной такая задача не стоит smile позже сделаю, а пока реюзаю класс годовалой давности...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0530 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.