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

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

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

 
 Ответить  Открыть новую тему 
> Динамическая матрица
сообщение
Сообщение #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 -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #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;
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Пионер
**

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

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


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

MaxInt div sizeof(Type)


Не совсем врубаюсь... Может проще как-нибудь можно?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #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-}), что не очень хорошо, ведь контроль отключается ДЛЯ ВСЕЙ программы...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #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 -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #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

 





- Текстовая версия 16.05.2024 19:47
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name