VladimirYU 0 1 сентября, 2009 Опубликовано 1 сентября, 2009 · Жалоба Столкнулся с непонятной вещью. Имеется некий класс TBase в хидере class TBase { public: TBase( UCHAR par1, UCHAR par2) // конструктор с двумя параметрами // Далее методы, данный и т.д. ......... ......... }; В file.cpp реализация. В прилложении создаются объявляются глообальные указатели и создаются два объекта 1 способ, не работает TBase *Obj[2]; // далее вызов конструкторов Obj[0] = new TBase( A, B); Obj[1] = new TBase( C, D); // Методы вызываются в основной программе Obj[0] ->Method1(); Obj[1] ->Method1(); .......... Поведение программы, как будто создан только один объет Obj[0] А если сделать вот так TBase *Obj0; TBase *Obj1; // далее вызов конструкторов Obj0 = new TBase( A, B); Obj1 = new TBase( C, D); // Методы вызываются в основной программе Obj0 ->Method1(); Obj1 ->Method1(); Все работает корректно. В чем может быть причина или где я не догоняю Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Quasar 20 6 сентября, 2009 Опубликовано 6 сентября, 2009 (изменено) · Жалоба VladimirYU привели бы весь код, или подробнее объясните, что значит программа ведет себя как будто создан только один объект? Судя по вашему коду, все должно работать корректно. Изменено 6 сентября, 2009 пользователем Quasar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SpSm 0 17 сентября, 2009 Опубликовано 17 сентября, 2009 · Жалоба А если объявить так? TBase (*Obj)[2]; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
visual_wind 0 17 сентября, 2009 Опубликовано 17 сентября, 2009 (изменено) · Жалоба To SmSp: В этом случае получится не массив из двух указателей на TBase, а указатель на массив из двух TBase. В коде, который привел VladimirYU, вроде все правильно, возможно, траблы были именно в реализации конструктора TBase или функции-члена Method1(), которые автор не привел. Изменено 17 сентября, 2009 пользователем visual_wind Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladimirYU 0 17 сентября, 2009 Опубликовано 17 сентября, 2009 · Жалоба To SmSp: В этом случае получится не массив из двух указателей на TBase, а указатель на массив из двух TBase. В коде, который привел VladimirYU, вроде все правильно, возможно, траблы были именно в реализации конструктора TBase или функции-члена Method1(), которые автор не привел. К сожалению реализация как конструкторов, так и методов скрыта и доступна только в виде библиотек .r90 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jorikdima 0 18 сентября, 2009 Опубликовано 18 сентября, 2009 · Жалоба Зачем в АВР динамически выделяемые объекты? И вообще, кто у вас там память выделяет/распределяет? Размер кучи достаточен? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
visual_wind 0 18 сентября, 2009 Опубликовано 18 сентября, 2009 · Жалоба To VladimirYU: Так а стало понятно, что не работает в варианте с массивом, или, поскольку все заработало в варианте без массива, то все ок и дальше нет смысла копаться? Если есть необходимость разбираться дальше: Из-под ссей можно еще просмотреть корректность работы оператора new (в разных ли местах выделяется память под рассматриваемые два экземпляра и с правильными ли параметрами вызываются конструкторы TBase). Возможно, кстати, что класс TBase перегружает operator new и там какой-то глюканат из-за оптимизации, например. Если есть полное описание класса TBase, можно еще после конструирования попытаться проверить корректность инициализации переменных класса TBase конструктором. Если полного описания класса нет, а только интерфейс, шанс еще есть в анализе дизассемблерного кода. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SpSm 0 18 сентября, 2009 Опубликовано 18 сентября, 2009 · Жалоба To SmSp: В этом случае получится не массив из двух указателей на TBase, а указатель на массив из двух TBase. В коде, который привел VladimirYU, вроде все правильно, возможно, траблы были именно в реализации конструктора TBase или функции-члена Method1(), которые автор не привел. Путаешь. TBase (*Obj)[2]; // обявлен массив из двух указателей на Obj TBase *(Obj[2]); // обявлен указатель на массив из двух Obj Не помню, у чего тут больше приоритет, поэтому предположил автору убедиться что объявлил он то что хотел. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
visual_wind 0 18 сентября, 2009 Опубликовано 18 сентября, 2009 (изменено) · Жалоба To SmSp: Могу и ошибаться. Чтоб лишний раз не спорить, предлагаю посмотреть Кернигана/Ричи, стр.111, последний абзац. Что касается приоритетов, то поскольку приоритет оператора[] выше приоритета оператора*, то использовать скобки в варианте TBase *(Obj[2]) смысла нет, а в варианте TBase (*Obj)[2] скобки как раз меняют приоритеты, то есть, сначала operator*, затем operator[], затем TBase. Итого, Obj есть указатель (operator*) на массив (operator[]) из двух ([2]) TBase. Изменено 18 сентября, 2009 пользователем visual_wind Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SpSm 0 18 сентября, 2009 Опубликовано 18 сентября, 2009 (изменено) · Жалоба Дык, ёлки! Всё верно, точнее у VladimirYU ошибка. Он обявил указатель на массив из двух TBase: TBase *Obj[2]; Не забываем что массив в си есть указатель на первый элемент массива, имеет тип *TBase. Так, Obj есть указатель на указатель на первый элемент массива из TBase. Первой строкой разименовал указатель (Obj[0] == *(Obj+0)), записал туда указатель на свежесозданный экземпляр TBase. Имеем указатель на указатель на массив, первый элемент которого проинициализирован: Obj[0] = new TBase( A, B); Вторая строка записывает указатель на свжесозданный экземпляр TBase по адресу Obj + 1: Obj[1] = new TBase( C, D); А это ошибка, т.к. используем указатель как массив, в итоге обращаясь к незанятой ячейки памяти. Всё равно что объявить TBase* pointer1; и затем обратиться *(pointer1 + 1) = bla bla; Отсюда и неправильное поведение программы. Надо внимательнее, это же си. Изменено 18 сентября, 2009 пользователем SmSp Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
visual_wind 0 18 сентября, 2009 Опубликовано 18 сентября, 2009 (изменено) · Жалоба To SmSp: Мое видение проблемы: У VladimirYU в том коде, что он привел, ошибок нет. Он НЕ объявлял указатель на массив из двух TBase, для чего надо использовать объявление TBase (*Obj)[2]. Он объявил массив из двух указателей на TBase, для чего и использовал правильное объявление TBase *Obj[2]. Это разные вещи, согласитесь. Чтобы не пускаться дальше в дискуссию об указателях на указатели и о том, что обозначает имя массива, я в Visual C++ Express Edition 2008 собрал простенький пример. class TBase { private: char char1; char char2; public: TBase( char c1, char c2 ): char1( c1 ), char2( c2 ) {} void Method1(){ cout << char1 << char2; } virtual ~TBase(){} }; TBase* tb[2] = { NULL, NULL }; int _tmain(int argc, _TCHAR* argv[]) { tb[0] = new TBase( '1', '2' ); tb[1] = new TBase( '3', '4' ); tb[0]->Method1(); tb[1]->Method1(); delete tb[0]; delete tb[1]; return 0; } У меня этот код работает правильно и печатает "1234". Можете проверить у себя. На мой взляд, проблема у VladimirYU в другом, но пока не понятно в чем. Изменено 18 сентября, 2009 пользователем visual_wind Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SpSm 0 18 сентября, 2009 Опубликовано 18 сентября, 2009 · Жалоба visual_wind, ты же сам написал, что приоритет оператора[] выше приоритета оператора*. Значит, VladimirYU объявил указатель на массив. А тот факт, что приведённый тобой код работает, означает что программа не затирает указатель по адресу tb+1, что в общем случае он может сделать и делает в программе VladimirYU (цитирую: "как будто создан только один объет Obj[0]"). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
visual_wind 0 18 сентября, 2009 Опубликовано 18 сентября, 2009 (изменено) · Жалоба То SmSp: По-моему, мы вместо помощи человеку начали разводить флейм и нарываемся на бан. И камень преткновения - что же на самом деле объявлено - указатель на массив из двух TBase или массив из двух указателей на TBase. Обратимся непосредственно к K&R: "Таким образом, если массив daytab передается некоторой функции f, то эту функцию можно было бы определить следующим образом f( char daytab[2][13] ){...} Вместо этого можно записать f( char daytab[][13] ){...} поскольку число строк здесь не имеет значения, или f( char (*daytab)[13] ){...} последняя запись декларирует, что параметр есть указатель на массив из 13 значений типа char. Скобки здесь необходимы, так как квадратные скобки [] имеют более высокий приоритет, чем *. Без скобок декларация f( char *daytab[13] ){...} определяет массив из 13 указателей на char. В более общем случае только первое измерение (соответствующее первому индексу) можно не задавать, все другие специфицировать необходимо" © K&R, стр.111-112, изд.2-е, переработанное,1992. Насколько я понимаю, у VladimirYU все в порядке в том коде, который он привел. Изменено 18 сентября, 2009 пользователем visual_wind Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Quasar 20 20 сентября, 2009 Опубликовано 20 сентября, 2009 · Жалоба Он обявил указатель на массив из двух TBase: Ни чего он такого не объявлял. Надо внимательнее, это же си. Вот именно. Возмите, да под какой-нибудь системой(которая способна ошибку сегментации выдать) соберите код: #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void){ int i,*arr[10],*arr2[10]; printf("Part 1\n"); for (i = 0; i < (sizeof(arr)/sizeof(int*));i++){ printf ("i = %d\n",i); arr[i] = (int*)malloc(sizeof(int)); *arr[i] = i; } for (i = 0; i < (sizeof(arr)/sizeof(int*));i++){ printf ("n = %d\n",*arr[i]); } printf ("Part 2\n"); for (i = 0; i < (sizeof(arr2)/sizeof(int*));i++){ printf ("i = %d\n",i); *arr2[i] = i; } return 0; } VladimirYU Проблема где-то не в массиве. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladimirYU 0 21 сентября, 2009 Опубликовано 21 сентября, 2009 · Жалоба VladimirYU Проблема где-то не в массиве. Я тоже к этому склоняюсь, но дело в том, что объекты в моем случае это физические приборы обращение к которым от "мамы" по SPI шине. Реализация класса, поддерживающего их, скрыта, есть только интерфейс .h и .r90. В общем пока обхожу эту проблему, но в дальнейшем придется разбираться. Всем спасибо за участие, за одно и лишний раз в стандарте покапался. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться