Здравствуйте, DSblizzard, Вы писали:
DS>template <class T> DS>void sozd(T* Mas_1x, int Razm) { DS> Mas_1x = new T [Razm]; DS>}
А ты не забыл, что указатель передается по значению? Здесь нужно возвращать указатель, а не void.
DS>void main() { DS> inic_mas_obozn_oper(); DS>}
Сделай int main()
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, LaptevVV, Вы писали:
LVV>А ты не забыл, что указатель передается по значению? Здесь нужно возвращать указатель, а не void.
Так лучше?
void sozd(T*& Mas_1x, int Razm)
LVV>Сделай int main()
Так и думал, что кто-нибудь на это укажет . Нет, дело не в этом. Проверьте в компиляторе — ни то, ни другое не решает проблему.
Программировать сложно. Но не программировать еще сложнее.
Здравствуйте, DSblizzard, Вы писали:
DS>Так и думал, что кто-нибудь на это укажет . Нет, дело не в этом. Проверьте в компиляторе — ни то, ни другое не решает проблему.
Страшно компилятору такое скармливать. Обидится компилятор, и не будет мне больше компилировать.
Здравствуйте, DSblizzard, Вы писали:
DS>Здравствуйте, LaptevVV, Вы писали:
LVV>>А ты не забыл, что указатель передается по значению? Здесь нужно возвращать указатель, а не void.
DS>Так лучше? DS>void sozd(T*& Mas_1x, int Razm)
Я б сделал непосредственно возврат указателя:
T * sozd(int Razm)
{ return new T[Razm]; }
LVV>>Сделай int main() DS>Так и думал, что кто-нибудь на это укажет . Нет, дело не в этом. Проверьте в компиляторе — ни то, ни другое не решает проблему.
Понятно, что к проблеме не относится... Но лучше сразу приучаться следовать стандарту... Иначе в один прекрасный день...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Ошибка в попытке передачи через ellipsis параметров, не являющихся POD-типами. Или даже жестче — ошибка вообще в попытке использования ellipsis. .
В Вашем случае, когда данные однородны (имеют один тип) их можно было просто поместить в последовательность, а её саму передать, например, в виде пары итераторов [начало, конец] или пары [начало, количество_элементов]. Незачем здесь городить ellipsis. Да и вообще стоит стремиться не использовать его во вновь разрабатываемом коде.
Т.е. ошибка в выбранном подходе к решению поставленной задаче.
P.S. А какая именно там ошибка возникает в том месте, которое Вы указали — хз. Места в стандарте C++ конкретного не нашёл, но подозреваю, что передача через ellipsis не POD-типов есть дело нехорошее.
EG>Ошибка в попытке передачи через ellipsis параметров, не являющихся POD-типами. Или даже жестче — ошибка вообще в попытке использования ellipsis. . EG>В Вашем случае, когда данные однородны (имеют один тип) их можно было просто поместить в последовательность, а её саму передать, например, в виде пары итераторов [начало, конец] или пары [начало, количество_элементов]. Незачем здесь городить ellipsis. Да и вообще стоит стремиться не использовать его во вновь разрабатываемом коде. EG>Т.е. ошибка в выбранном подходе к решению поставленной задаче. EG>P.S. А какая именно там ошибка возникает в том месте, которое Вы указали — хз. Места в стандарте C++ конкретного не нашёл, но подозреваю, что передача через ellipsis не POD-типов есть дело нехорошее.
1. Нестандартный синтаксис prisv(blablabla, T ...) — типизированное отточие.
2. Если компилятор наплевал на T и счёл, что это обычное нетипизированное отточие, то в функцию передаются const char*, а читаются std::string (va_arg(Args,T) где T = string).
Это неопределённое поведение — попросту, неадекватный reinterpret_cast. Что из него получится — никому не известно.
В ATL/MFC были предприняты специальные меры, чтобы const CString совпадал с const char*, поэтому там такие фокусы возможны, хотя это и на грани фола.
3. Если же компилятор умеет обращаться с типизированным отточием — то до какой степени это умение распространяется? Может ли он адекватно передавать не-POD и так же адекватно их читать?
Здравствуйте, elcste, Вы писали:
К>>1. Нестандартный синтаксис prisv(blablabla, T ...) — типизированное отточие. E>Это, кстати, стандартный синтаксис. Здесь четыре обязательных параметра (последний — неименованный).
Ай пардон пардон!
Тогда всё вообще встало на свои места.
Первый аргумент из перечня строковых литералов
— был в точке вызова приведён к string,
— некорректное va_start(Args,Arg1) (не на последнем обязательном аргументе) удачно сфокусировало Args на этот первый string
— некорректное va_arg(Args,string) (потому что не POD) удачно получило доступ к string
ну и дальше всё срослось.
Второй аргумент из того перечня
— был передан, как и полагается, в виде const char*
— va_arg(Args,string) обратилось к нему как к const string&
к счастью, оказалось, что первый член string — это const char*, поэтому строку удалось прочесть
Но оператор присваивания уже, скорее всего, сошёл с ума и в Mas[1] записал какую-то фигню.
Третий аргумент
— опять же, const char*
— va_arg(Args,string) в прошлый раз стремительно прыгнул вперёд на sizeof(string), а не на sizeof(const char*)...
Кстати говоря, MasOboznOper — не инициализированный указатель на массив строк.
Так что мы давно уже ездим кому-то по мозгам...
Здравствуйте, Кодт, Вы писали:
К>Кстати говоря, MasOboznOper — не инициализированный указатель на массив строк. К>Так что мы давно уже ездим кому-то по мозгам...
В смысле, не инициализирован при объявлении? А зачем, простите за глупый вопрос? После создания он инициализируется, а до создания я его не использую. А если попытаюсь использовать, то это мои проблемы — это будет указывать не на обычный недосмотр, а на логическую ошибку, нужно будет переписать фрагмент по-другому.
"плохо отформатирован". К сожалению, обнаружил после отправки, а возможности редактирования нет. Почему, интересно?
Программировать сложно. Но не программировать еще сложнее.
Здравствуйте, DSblizzard, Вы писали:
К>>Кстати говоря, MasOboznOper — не инициализированный указатель на массив строк. К>>Так что мы давно уже ездим кому-то по мозгам...
DS>В смысле, не инициализирован при объявлении? А зачем, простите за глупый вопрос? После создания он инициализируется, а до создания я его не использую.
Нет, он у тебя нигде не присваивается!
0) Определяешь глобальную переменную. Она инициализируется нулём.
1) Передаёшь в sozd(T*,int) её значение — т.е. нуль.
2) sozd() выполняет присваивание локальной переменной, создавая утечку.
3) Передаёшь в prisv(T*,int,T,...) всё тот же нуль.
4) Наконец, внутри prisv() разыменовываешь этот самый нуль операторами [] — вот тебе и стрельба.
Здравствуйте, Кодт, Вы писали:
К>0) Определяешь глобальную переменную. Она инициализируется нулём. К>1) Передаёшь в sozd(T*,int) её значение — т.е. нуль. К>2) sozd() выполняет присваивание локальной переменной, создавая утечку. К>3) Передаёшь в prisv(T*,int,T,...) всё тот же нуль. К>4) Наконец, внутри prisv() разыменовываешь этот самый нуль операторами [] — вот тебе и стрельба.
В ответе LaptevVV'у я же вроде исправил эту описку.
Программировать сложно. Но не программировать еще сложнее.