Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Не пойму почему ошибка при SetLetngth [D7, XP]


Страницы:   1 2

kostyl_kostyl ©   (2009-09-15 17:55:00) 

Не пойму почему ошибка при SetLetngth
Есть объект, у которого дискретно увеличиваются массивы свойств
procedure TMyObject.Add(NewValue: Integer);
var
 L: Integer;
begin
 L := length(Values);
 if (L  < Count + 1) then
 begin
    SetLength(Values, L + 10);
    SetLength(OtherValues, L + 10);
    SetLength(OtherOtherValues, L + 10);
 end;
 Values[Count] := NewValue;
 Inc(Count);
end;

То есть три свойства это массивы и я выделяю постепенно память для них. Все одни синхронизированы, то есть всегда имеют одинаковую длину?
И вот  SetLength(OtherValues, L + 10); происходит ошибка access violation read of adress...
Пробовал компилировать с {$R+}, все равно не пойму как понять почему такое бывает.


sniknik   (2009-09-16 16:09:00) [1]

имхо, это неуважение и оскорбление отвечающих, которым приходится "выпрашивать" проблемный код.  нет так нет, на нет и суда нет. и ветки нет.


Сергей М.   (2009-09-16 16:05:00) [2]


> я не делаю подобных операций


Ну другие какие-то делаешь, смысл от этого не меняется - поле-то испорчено у тебя ..


kostyl_kostyl   (2009-09-16 15:51:00) [3]

а, понятно, но я не делаю подобных операций просто пишу/читаю в/из ячейки integer переменную integer и за length массивов не выхожу(тогда бы, как уже указывали, был бы другой эксцепшн). Еще примечательно то, что эта ошибка при одном и том же ходе программы, может возникать, а может и не возникать....
Ух...((( замаялся я уже ((


Сергей М.   (2009-09-16 15:16:00) [4]


> Пусть адрес поля SomeField1 в памяти приложения равен 100
>
> Тогда адрес поля SomeField 2


Сергей М.   (2009-09-16 15:15:00) [5]


> как это "внутри" просиходит?


Оч просто.

Для наглядности:
Пусть type Чего-то_там = byte;

Пусть адрес поля SomeField1 в памяти приложения равен 100

Тогда адрес поля SomeField1 будет равен 100 + SizeOf(byte) = 100 + 1 = 101, а адрес поля OtherValues будет равен 100 + SizeOf(byte) + SizeOf(byte) = 100 + 1 + 1 = 102

Пусть ожидаемое корректное значение поля OtherValues равно 1, т.е. "единица" хранится в младшем байте этого поля, имеющем адрес 102.

Пусть в поле SomeField1 хранится значение 3, а в поле SomeField2 - значение 4.

Процедура Move(), вызываемая якобы для копирования данных из поля SomeField1 в поле SomeField2, ошибочно запишет 2 (!!!) байта данных в область памяти, начинающуюся с адреса 101 и заканчивающуюся адресом 102, т.е. "зацепит" данные в поле OtherValues, в результате чего значение поля OtherValues изменится и станет равным 4, хотя явных обращений к этому полю не было и было бы справедливо ожидать в нем значение 1.. если бы не ошибочный вызов Move(), "загадивший" это поле.


kostyl_kostyl   (2009-09-16 14:46:00) [6]


> Сергей М. ©   (16.09.09 14:32) [21]

я просто из вашего примера не понял как портиться OtherValues? как это "внутри" просиходит?


Сергей М.   (2009-09-16 14:32:00) [7]


> как за этим следить


Ну как ? Глазами и головой, как же еще ?)


> как это вообще происходить может?


В смысле ?
Как умудриться сделать ошибку в своем коде что ли ?


kostyl_kostyl   (2009-09-16 14:22:00) [8]


> Сергей М. ©   (16.09.09 13:39) [19]


> //гадим в поле OtherValues, не обращаясь к нему явно ни
> по чтению ни по записи

Тю, а как за этим следить и как это вообще происходить может?


Сергей М.   (2009-09-16 13:39:00) [9]


> там типа конкуренция за область памяти какая то происходит?

О "конкуренции" можно говорить только в мультипоточном приложении.
А поскольку ты о мультипоточности своего приложения ничего не сказал, то и конкуренции никакой быть не может.


> Я же просто в ячейку по адресу пишу значение и всё?


Я не знаю, что ты там и куда пишешь, но вот тебе пример:

TMyObject = class(..)
..
 SomeField1, SomeField2: Чего-то_там;
 OtherValues: array of Integer;
..  
end;

..
//гадим в поле OtherValues, не обращаясь к нему явно ни по чтению ни по записи
   Move(SomeField1, SomeField2, SizeOf(Чего-то_там) + 1);


kostyl_kostyl   (2009-09-16 13:28:00) [10]


> Сергей М. ©   (16.09.09 13:07) [17]

А как же записью? Я же просто в ячейку по адресу пишу значение и всё? Или там типа конкуренция за область памяти какая то происходит?


Сергей М.   (2009-09-16 13:07:00) [11]

Чтением, конечно, не испортишь.
А записью запросто можно.
Причем испортить можно даже не обращаясь к этому полю, а обращаясь к вышефигурирующим полям того же объекта.


kostyl_kostyl   (2009-09-16 13:02:00) [12]


> Исключение бы совсем другое было.

ну да, тогда бы индекс за пределы вышел бы...

> Свой ты не показал

Ну так а как я чтением/записью могу испортить память? Размер я меняю только в одном месте, а остальные операции только чтение/запись?


Сергей М.   (2009-09-16 12:50:00) [13]


> как это можно сделать?


Вариантов нагадить существует множество.
Свой ты не показал)


> Может ..я делаю SetLength(OtherValues, 20);  а где то пишу или читаю
> OtherValues[22]


Не может.
Исключение бы совсем другое было.


kostyl_kostyl   (2009-09-16 12:36:00) [14]


> Костыль тут простой - кто-то или что-о загадило содержимое
> структуры

Вот я тоже так думаю, но как это можно сделать? Вот в чем вопрос.
Может эта бяка происходит когда я пишу и читаю OtherValues? Может например я делаю SetLength(OtherValues, 20);  а где то пишу или читаю OtherValues[22]?


Anatoly Podgoretsky   (2009-09-16 11:45:00) [15]

> MBo  (16.09.2009 08:24:11)  [11]

Лучше ее делать пропорционально, как в TList


Anatoly Podgoretsky   (2009-09-16 11:44:00) [16]

> Achpile  (16.09.2009 06:58:10)  [10]

С этим полный порядок, проверка на наличие места в массиве.


MBo   (2009-09-16 08:24:00) [17]

>Achpile ©   (16.09.09 06:58) [10]
Чтобы реже делать реаллокацию памяти


Achpile   (2009-09-16 06:58:00) [18]

Мне интересно, почему прибавляется 1 элемент, а длина массива увеличивается на 10...


KilkennyCat   (2009-09-16 05:14:00) [19]


> Rouse_ © (15.09.09 23:59) [7]

нормально, но странно: я все жду, когда начнется использоваться параметр процедуры, и опа! в конце, да и так, невлиятельно.


Германн   (2009-09-16 00:42:00) [20]

Лично я вообще ничего не понял из сабжа. Кроме того, что приведенный код даёт ошибку.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо