Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.11.01;
Скачать: CL | DM;

Вниз

Не пойму почему ошибка при SetLetngth   Найти похожие ветки 

 
kostyl_kostyl   (2009-09-15 17:55) [0]

Не пойму почему ошибка при 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+}, все равно не пойму как понять почему такое бывает.


 
palva ©   (2009-09-15 19:07) [1]

Что такое массив свойств? Как в объекте описана Values?


 
Сергей М. ©   (2009-09-15 21:37) [2]


> все равно не пойму как понять почему


Песня !


 
Сергей М. ©   (2009-09-15 21:43) [3]


> SetLength(OtherValues, L + 10); происходит ошибка access
> violation


Костыль тут простой - кто-то или что-о загадило содержимое структуры, скрываемой за идентификатором OtherValues


 
Rouse_ ©   (2009-09-15 23:22) [4]


> Есть объект, у которого дискретно увеличиваются массивы
> свойств

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


 
KilkennyCat ©   (2009-09-15 23:43) [5]

последние две строчки тоже неплохо выглядят.


 
Achpile   (2009-09-15 23:46) [6]

делаешь так:

type
 TValue = record
   Value,
   OtherValue,
   OtherOtherValue: integer;
 end;

var
 Values: array of TValue;

procedure Add(NewValue: TValue);
begin
 SetLength(Values, Length(Values) + 1);
 Values[High(Values)] := NewValue;
end;

И все... Чтобы обратиться к любому элементу класса делаешь так:

Values[i].Value
или
Values[1].OtherValue

Ну вообщем как-то так... i - это индекс элемента, к которому хочешь обратиться...


 
Rouse_ ©   (2009-09-15 23:59) [7]


> KilkennyCat ©   (15.09.09 23:43) [5]
>
> последние две строчки тоже неплохо выглядят.

Нормально выглядят, там же проверка выше :)
Тут Сергей прав - где-то засираются указатели...


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

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


 
KilkennyCat ©   (2009-09-16 05:14) [9]


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

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


 
Achpile ©   (2009-09-16 06:58) [10]

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


 
MBo ©   (2009-09-16 08:24) [11]

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


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

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

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


 
Anatoly Podgoretsky ©   (2009-09-16 11:45) [13]

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

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


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


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

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


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


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


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


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


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


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


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

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

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

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


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

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


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


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

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


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


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

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


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


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

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

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


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


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


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

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


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


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


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


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


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


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


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

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


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


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


Оч просто.

Для наглядности:
Пусть 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(), "загадивший" это поле.


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


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


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

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


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


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


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


 
sniknik ©   (2009-09-16 16:09) [27]

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



Страницы: 1 вся ветка

Текущий архив: 2009.11.01;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.019 c
2-1252341586
fics)
2009-09-07 20:39
2009.11.01
Вопрос по копмонентам


15-1251978221
Ak47
2009-09-03 15:43
2009.11.01
проверить содержится ли значение в массиве


15-1251979701
stas
2009-09-03 16:08
2009.11.01
Размер скачиваемого файла


1-1222090596
Dmitry S
2008-09-22 17:36
2009.11.01
Как задать толщину линии TPen.Width равную 1 мм?(продожение темы)


15-1251803846
DVM
2009-09-01 15:17
2009.11.01
Разбор командной строки на имя файла и параметры