Страница 1 из 2
Перехлёстывающиеся массивы
Добавлено: 10 июн 2008, 01:08
Фоб
Это просто ужос!
Я 6 часов потратил на поиск ошибки.
И обнаружил ну совсем невменяемую хрень.
Итак, есть 2 класса:
Код: Выделить всё
класс2{
float* массив2
void f2(){
// наращивание массива2
массив2 = new float[цифра]
}
}
класс1{
float* массив1
класс2 к2.
void f1(){
// наращивание массива1
массив1 = new float[цифра]
}
}
Кто-нибудь может хотя бы примерно предположить, почему в результате заполнения циферками массива класс1.массив1, нулевой элемент массива класс1.к2.массив2 получает значение типа 1000653463.
Индексация в процедуре заполнения первого массива - абсолютно верная.
Адреса массивов охренительно далеко друг от друга.
Я проверил и перепроверил всё - никаких зацепок, в чём причина. Только иррациональное следствие: пишем в первый массив, и в одном случае из ста сбивается нулевой элемент второго массива.
Операция переноса значений в функциях f1 и f2 - тоже в порядке, я расставлял ловушки везде, где только можно, и однозначно установил место в программе, в котором нулевой элемент сбивается - СРАЗУ ЖЕ после заполнения первого массива.
Конечно, я могу использовать vector вместо массивов, и наверняка фигня исчезнет, но не хочется оставлять эту ошибку непонятой, особенно с учётом 6 часов борьбы с этим привидением.
Re: Перехлёстывающиеся массивы
Добавлено: 10 июн 2008, 13:13
Romeo
Уверен, что ты напутыл с размерами или индексами во время заполнения. Выкладывай сюда код полностью. Демагогия - это хорошо, но реальный код - лучше
Re: Перехлёстывающиеся массивы
Добавлено: 10 июн 2008, 17:01
airyashov
Надо полный код смотреть
Re: Перехлёстывающиеся массивы
Добавлено: 10 июн 2008, 20:49
Фоб
Эх, великоват он... я думал, может кто с общих позиций чего подскажет... ну да ладно, вот: (лишнее я всё жостко повырезал, иначе нефорумных размеров код был бы)
Код: Выделить всё
class promoter{ // элемент дерева экспрессии/ингибирования
public:
int* a; // тот самый массив, в чей нулевой элемент незаконно вписывают хрень
int a_size;
void add_leaf(int leaf_n){ // процедура наращивания того самого массива а, в чей нулевой элемент попадает хрень
if (!a_size){
a_size = 1;
a = new int[a_size];
a[0] = leaf_n; // тут всё нормально записывается - проверял
}
else{
int* temp_a = new int[a_size + 1];
int i;
for (i = 0; i < a_size; i++)
temp_a[i] = a[i];
temp_a[a_size] = leaf_n;
delete(a); // кстати, эта инструкция не лишняя часом?
a_size++;
a = new int[a_size];
for (i = 0; i < a_size; i++){
a[i] = temp_a[i];
}
}
}
};
class gene{
public:
vector<promoter> eTree;
vector<promoter> iTree;
genome* myGenome;
gene(int tree_size, int an, genome* g){
int i;
myGenome = g;
for (i = 0; i < tree_size; i++)
add_random_promoter(); // тут заполняются eTree и iTree
}
};
class genome{
public:
float* p; // когда пишем в этот массив, в а[0] одного из vector<gene> genes (а в нём одного из eTree) пишется хрень
vector<gene> genes;
int p_length; // по умолчанию = 9
int p_real; // по умолчанию = 9
int p_feel; // по умолчанию = 6
genome(){};
genome(int p_r, int p_f, int rgenes){
p_feel = p_f;
p_real = p_r;
p_length = p_r;
p = new float(p_length);
int i;
for (i = 0; i < rgenes; i++)
create_random_gene(1 + random(INIT_TREE_SIZE));
}
void create_random_gene(int pep_dep = 1){
int n = p_feel + random(p_length - p_feel + 1);
if (n == p_length){
p_length++;
p = new float[p_length];
}
genes.push_back(gene(pep_dep, n, this));
}
void update_perception(float* obj_p){
int i;
for (i = 0; i < p_feel; i++)
p[i] = obj_p[i]; // !!! цикл №1, после которого в нулевой элемент одного из массивов а пишется хрень; (замечу, что p_feel == 6, что меньше, чем длина массива p, равная 9)
}
void genes_work(){
int i;
int c_range = p_length - p_feel;
float* temp_p = new float[c_range];
for (i = 0; i < c_range; i++)
temp_p[i] = 0;
for (i = 0; i < genes.size(); i++) {
int j;
for (j = 0; j < genes[i].eTree.size(); j++) {
if (genes[i].eTree[j].a_size) {
if (genes[i].eTree[j].a[0] > 10) {
genes[i].eTree[j].a[0] = 1;
}
}
}
temp_p[genes[i].n - p_feel] = p_or(temp_p[genes[i].n - p_feel], genes[i].work());
}
for (i = p_feel; i < p_length; i++) { //
p[i] = temp_p[i - p_feel]; // !!! цикл №2, после которого в нулевой элемент одного из массивов а может попасть хрень;
} //
}
};
Re: Перехлёстывающиеся массивы
Добавлено: 10 июн 2008, 20:58
Фоб
Блиииииииииин! Ну надо же! Это, наверное, от непрофессионализма.
Секунду назад выложил этот код, взглянул на появившийся код и взгляд мой упал на строчку
p = new float(p_length);
Скобочки не квадратные..............
Неужели из-за этого я вчера столько мучился :/
Ужос
Re: Перехлёстывающиеся массивы
Добавлено: 10 июн 2008, 22:26
Romeo
Угу, похоже.
Re: Перехлёстывающиеся массивы
Добавлено: 11 июн 2008, 11:19
Хыиуду
[offtop]
Вот за подобные вещи я Си и не люблю. Знает, скотина, что будет все неправильно, но в жизни не признается!
[/offtop]
Re: Перехлёстывающиеся массивы
Добавлено: 11 июн 2008, 12:44
Romeo
Хыиуду писал(а):[offtop]
Вот за подобные вещи я Си и не люблю. Знает, скотина, что будет все неправильно, но в жизни не признается!
[/offtop]
Нет, ты не прав. То, что действительно неверно, то репортится, как ошибка. В данном же случае мы наблюдаем допустимую форму записи оператора new. Она называется аллокацией в существующей области памяти. В скобках ожидается поинтер, указывающий на эту область. Естественно
p_length не является этим поинтером, потому всё работает криво.
Re: Перехлёстывающиеся массивы
Добавлено: 11 июн 2008, 14:17
Albor
Romeo писал(а):Нет, ты не прав. То, что действительно неверно, то репортится, как ошибка. В данном же случае мы наблюдаем допустимую форму записи оператора new. Она называется аллокацией в существующей области памяти. В скобках ожидается поинтер, указывающий на эту область. Естественно p_length не является этим поинтером, потому всё работает криво.
Romeo, разве в скобках ожидается указатель? По моему, данная строка интерпретируется как выделение памяти под переменную типа float, инициализируемую значением типа int. То есть, после выделения памяти, по адресу, помещённому в
p будет находится значение, равное
p_length
Re: Перехлёстывающиеся массивы
Добавлено: 11 июн 2008, 15:16
Romeo
" писал(а):Romeo, разве в скобках ожидается указатель? По моему, данная строка интерпретируется как выделение памяти под переменную типа float, инициализируемую значением типа int. То есть, после выделения памяти, по адресу, помещённому в p будет находится значение, равное p_length
Верно говоришь,
Albor . Я невнимательно посмотрел на строку. Поинтер на область указывается после
new, но
до имени типа. Но то, что такой синтаксис позволителен - в этом я прав