IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

> Динамическая матрица
kent
сообщение 30.07.2005 20:16
Сообщение #1


Пионер
**

Группа: Пользователи
Сообщений: 50
Пол: Мужской
Реальное имя: Андрей

Репутация: -  1  +


Захотел использовать динамическую матрицу в задаче, но что то не получается... Попытался сначала сделать ввод вывод, но вводишь к примеру M = 3, N = 3...

Вводишь
1 2 3
1 2 3
1 2 3

Выводит
1 1 1
1 1 2
1 2 3

Вот код:

uses crt;
var M,N : Integer;
type
MyType = Integer;
type
MyMatrix = array [1..1,1..1] of MyType;
TMatrix = ^MyMatrix;

{-----------------------------------------------}
Procedure ReadMatrix(var mx : TMatrix);
var i,j : Integer;
begin
for i := 1 to M do
for j := 1 to N do begin
Write('Element [',i,',',j,']:');
ReadLn(mx^[i,j]);
end;
end;
{-----------------------------------------------}

{-----------------------------------------------}
Procedure WriteMatrix(var mx : TMatrix);
var i,j : Integer;
begin
for i := 1 to M do
for j := 1 to N do begin
Write(mx^[i,j]:3);
if j = N then WriteLn;
end;
end;
{-----------------------------------------------}

var a : TMatrix;
Size : Word;

begin
{$R-}
Clrscr;
Write('Input M:');
ReadLn(M);
Write('Input N:');
ReadLn(N);
Size := M * N * SizeOf(MyType);
GetMem(a,Size);
WriteLn('Input Matrix:');
ReadMatrix(a);
WriteLn;
WriteLn('Source Matrix:');
WriteMatrix(a);
FreeMem(a,Size);
Readkey;
end.



Подскажите что не так...

Сообщение отредактировано: kent - 30.07.2005 20:39
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов(1 - 5)
volvo
сообщение 30.07.2005 21:18
Сообщение #2


Гость






Цитата(kent @ 30.07.05 20:16)
Подскажите что не так...

smile.gif Подсказываю:
GetMem(a,Size);

Если бы все было так просто... Вообще-то описания типов должны быть такими:
type
MyType = Integer;
PVector = ^TVector;
TVector = Array[1 .. maxInt div sizeof(MyType)] Of MyType;

PMatrix = ^TMatrix;
TMatrix = Array[1 .. MaxInt div sizeof(PVector)] Of PVector;


Ну, и выделение/освобождение памяти, соотвественно:
  ReadLn(M);
GetMem(a, M*SizeOf(PVector));
ReadLn(N);
For i := 1 To M Do
GetMem(a^[i], N*SizeOf(MyType));


Кстати, в процедуре распечатки матрицы у тебя лишний If - зачем?
Вот так не лучше? ;)
Procedure WriteMatrix(mx : PMatrix);
var i, j : Integer;
begin
for i := 1 to M do begin
for j := 1 to N do
Write(mx^[i]^[j]:3);
WriteLn;
end;
end;
 К началу страницы 
+ Ответить 
kent
сообщение 30.07.2005 21:57
Сообщение #3


Пионер
**

Группа: Пользователи
Сообщений: 50
Пол: Мужской
Реальное имя: Андрей

Репутация: -  1  +


Попробовал сделать так, выводит правильно, но вместо того чтобы ждать нажатия клавиши (Readkey), выдает Runtime - error 204... blink.gif
И ещё вопрос, что означает?

MaxInt div sizeof(Type)


Не совсем врубаюсь... Может проще как-нибудь можно?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 30.07.2005 22:26
Сообщение #4


Гость






Цитата(kent @ 30.07.05 21:57)
выводит правильно, но вместо того чтобы ждать нажатия клавиши (Readkey), выдает Runtime - error 204... blink.gif

Значит, что-то неправильно делаешь (эта ошибка возникает при неправильной работе с указателями через GetMem/FreeMem)...
Вот так должно происходить освобождение:
  For i := 1 To M Do
FreeMem(a^[i], N*SizeOf(MyType));
FreeMem(a, M*SizeOf(PVector));

Цитата(kent @ 30.07.05 21:57)
И ещё вопрос, что означает?
MaxInt div sizeof(Type)

Может проще как-нибудь можно?

Вообще-то я пропустил, там должно быть вот так:
TVector = Array[1 .. 2 * maxInt div sizeof(MyType)] Of MyType;
:p2:
Это означает, что максимальное число элементов массива рассчитывается исходя из следующих соображений: максимальный размер массива в Турбо-Паскале = 64Кбайта, что соответствует 2*maxInt. Но столько элементов в массив поместится только, если размер каждого = 1 байту. У тебя размер каждого элемента = SizeOf(MyType), вот и дели макс. возможный размер на размер каждого элемента, чтобы получить макс. число элементов в массиве... При таком способе у тебя НИКОГДА не произойдет выхода за пределы массива...

Можно, в принципе, оставить как было у тебя:
type
...
TVector = Array[1 .. 1] Of MyType;
...
TMatrix = Array[1 .. 1] Of PVector;

, но тогда тебе придется отключать контроль выхода за пределы массива ({$R-}), что не очень хорошо, ведь контроль отключается ДЛЯ ВСЕЙ программы...
 К началу страницы 
+ Ответить 
kent
сообщение 30.07.2005 22:46
Сообщение #5


Пионер
**

Группа: Пользователи
Сообщений: 50
Пол: Мужской
Реальное имя: Андрей

Репутация: -  1  +


Сейчас все ОК, никаких ошибок... smile.gif


Цитата
Значит, что-то неправильно делаешь (эта ошибка возникает при неправильной работе с указателями через GetMem/FreeMem)...

Немного не так у меня было...
Вместо:
  For i := 1 To M Do
FreeMem(a^[i], N*SizeOf(MyType));
FreeMem(a, M*SizeOf(PVector));

Стояло:

FreeMem(a, M*SizeOf(PVector));
For i := 1 To M Do
FreeMem(a^[i], N*SizeOf(MyType));



А насчет размерности масива, буду наерное использовать твой вариант, дальше сложные задачки идут и без дополнительных массивов наверное не обойтись, так что ({$R-}) мне будет только мешать...

Спасибо тебе большое, что так подробно всё объяснил... :thanks:
Жалко тут рейтинга нет с меня два ++... smile.gif

Сообщение отредактировано: kent - 30.07.2005 22:47
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 30.07.2005 22:58
Сообщение #6


Гость






Цитата(kent @ 30.07.05 22:46)
Стояло:

FreeMem(a, M*SizeOf(PVector));
For i := 1 To M Do
    FreeMem(a^[i], N*SizeOf(MyType));


Я так и думал... Это очень распространенная ошибка: дело в том, что вообще-то память должна освобождаться в порядке, противоположном ее выделению. То есть, если выделялось так:
GetMem(x1, ...);
GetMem(x2, ...);
...

То освобождаться должно так:
...
FreeMem(x2, ...);
FreeMem(x1, ...);

Это же желательно взять за правило в случае работы с New/Dispose...
А я кроме этого (по возможности) придерживаюсь такого же порядка при работе с файлами, то есть то, что открывается последним, закрывается первым. :yes:
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 21.06.2025 15:06
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"