Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2009.11.01;
Скачать: [xml.tar.bz2];

Вниз

Не пойму почему ошибка при 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.089 c
15-1251750605
Юрий
2009-09-01 00:30
2009.11.01
С днем рождения ! 1 сентября 2009 вторник


15-1252182612
Юрий
2009-09-06 00:30
2009.11.01
С днем рождения ! 6 сентября 2009 воскресенье


15-1251805431
netdancer
2009-09-01 15:43
2009.11.01
BDE и Windows Vista


4-1221071670
тимохов
2008-09-10 22:34
2009.11.01
Надо ли инициализировать Offset у структуры OVERLAPPED?


15-1252052990
БарЛог
2009-09-04 12:29
2009.11.01
Девайс лок для виндовс





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский