"Ошибка сегментирования" помогите! (Программа нормально работает в отладчике, но падает без него)
Модератор: Модераторы разделов
-
- Сообщения: 24
- ОС: linux Fedora Core
"Ошибка сегментирования" помогите!
Помогите кто-нибудь пожалуйста!
Я никогда еще с таким не встречался:
Однопаточная программа, при выполнении в отладчике работает нормально, а вот когда запускаю без него, то сразу падает с ошибкой "ошибка сегментирования". Падает при вызове функции, притом, в отладчике наблюдается, что функция вызывается нормально и правильно отрабатывает, а вот без отладчика на ней же валится. Подскажите пожалуйста хоть что-нибудь...
Заранее очень благодарен.[font="Arial Black"][font]
Я никогда еще с таким не встречался:
Однопаточная программа, при выполнении в отладчике работает нормально, а вот когда запускаю без него, то сразу падает с ошибкой "ошибка сегментирования". Падает при вызове функции, притом, в отладчике наблюдается, что функция вызывается нормально и правильно отрабатывает, а вот без отладчика на ней же валится. Подскажите пожалуйста хоть что-нибудь...
Заранее очень благодарен.[font="Arial Black"][font]
-
- Сообщения: 1338
- Статус: We are all Kosh
- ОС: Fedora 10
-
- Сообщения: 24
- ОС: linux Fedora Core
Re: "Ошибка сегментирования" помогите!
Спасибо!
Код - не проблема, проблема в том, что не знаю даже с чего начать. Дела обстоят так: есть shared модуль, в котором реализована функциональность загрузчика. Этот загрузчик позволяет загружать и выполнять функции из библиотек, скомпилированых под винду. Теперь: ПОД ОТЛАДЧИКОМ я с группой ребят проверяли много раз - загрузчик действительно работает и возвращает указатели на функции, которые потом реально выполняются и работают, но вот только вне отладчика все плохо.
В следующем фрагменте программа падает на вызове ф-ии SetNameInfo:
BOOL CFrameWork::LoadScanners()
{
char* path = _pwd();
strcat(path,"/SCANNERS");
char *BASES = new char[strlen(path)+15];//, "bases.cav");
sprintf(BASES,"%s/bases.cav",path);
LARGE_INTEGER li;
li.HighPart=0;
li.LowPart=file_size(BASES);
if (!(m_hres = LoadModule(BASES,&li))) return false;
NAMING* naming;
DWORD naming_size;
char *names;
if (!(naming = (NAMING*)get_base(IDR_NAMING, &naming_size)) ||
!(names = (char*)get_base(IDR_MALWARE_FAMILIES)))
{
delete BASES, BASES=NULL;
return false;
}
delete BASES, BASES=NULL;
delete path, path = NULL;
path = _pwd();
strcat(path,"/SCANNERS");
char *common = new char[strlen(path)+15];
sprintf(common,"%s/common.cav",path);
li.HighPart=0;
li.LowPart=file_size(common);
LPVOID hmod;
if (!(hmod = LoadModule(common,&li)))
{
delete common, common = NULL;
return false;
}
delete common, common = NULL;
void (CDECL* SetNameInfo)(NAMING* , const char*, unsigned) =
(void (CDECL* )(NAMING* , const char*, unsigned ))GetProcAddr(hmod, 114);
if (!SetNameInfo)
{
UnloadModule(hmod);
return false;
}
SetNameInfo(naming, names, naming_size);
m_hcom = (LPVOID)hmod;
LoadScanners(path);
//DEBUG
//delete path, path=NULL;
return m_first != 0;
}
Сама SetNameInfo функция находится в библиотеке, которую разберает загрузчик и выглядет так:
NAMING* g_malware_types_and_names;
const char* g_malware_names;
unsigned g_malware_naming_size;
void SetNameInfo(NAMING* malware_types_and_names, const char* malware_names, unsigned malware_naming_size)
{
g_malware_types_and_names = malware_types_and_names;
g_malware_names = malware_names;
g_malware_naming_size = malware_naming_size;
}
Т. е.: она не делает ничего криминального, просто инициализирует глобальные переменные... вот на ней и валится...
-
- Сообщения: 636
- ОС: Gentoo GNU/Linux
Re: "Ошибка сегментирования" помогите!
Код: Выделить всё
char* path = _pwd();
strcat(path,"/SCANNERS");
память кто будет выделять под удлинение строки?
именование переменных говорит о коде под оффтопик. имхо, не должен тут обсуждаться
код не форматирован, читабельность -10
все сказанное есть имхо...
-
- Сообщения: 436
- Статус: Интересующийся новичок
- ОС: Debian GNU/Linux 4 & 5
Re: "Ошибка сегментирования" помогите!
Как вы понимаете, я могу только догадываться, что вы знаете, что в path достаточно места для strcat...
char *BASES = new char[strlen(path)+15];//, "bases.cav");
delete BASES, BASES=NULL;
Вы вызываете delete к тому, что размещено new [] - Error.
delete BASES, BASES=NULL;
delete path, path = NULL;
Как вы понимаете, я могу только догадываться, что вы знаете, что path было размещено new (а это оч вряд ли), и именно так его нужно удалять, и его удалять должны вы... Мне кажется что опять вы вызываете delete к тому, что вероятно размещено new [] - Error.
Как вы понимаете, дальше там у вас такого же выше крыши...

Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
-
- Сообщения: 24
- ОС: linux Fedora Core
Re: "Ошибка сегментирования" помогите!
sergio писал(а): ↑18.09.2007 16:18
Как вы понимаете, я могу только догадываться, что вы знаете, что в path достаточно места для strcat...
char *BASES = new char[strlen(path)+15];//, "bases.cav");
delete BASES, BASES=NULL;
Вы вызываете delete к тому, что размещено new [] - Error.
delete BASES, BASES=NULL;
delete path, path = NULL;
Как вы понимаете, я могу только догадываться, что вы знаете, что path было размещено new (а это оч вряд ли), и именно так его нужно удалять, и его удалять должны вы... Мне кажется что опять вы вызываете delete к тому, что вероятно размещено new [] - Error.
Как вы понимаете, дальше там у вас такого же выше крыши...
_pwd() выделяет на 20 байт больше, поэтому ошибка никак не здесь... согласен на все 100%, что такой подход является больше чем неправельным, но на данный момент мне нужно, чтоб срочно заработала основа, потом я обязательно поправлю все эти глупые моменты.
P.S.: извиняйте за нечитабильность кода, я первый раз тут))
-
- Сообщения: 436
- Статус: Интересующийся новичок
- ОС: Debian GNU/Linux 4 & 5
Re: "Ошибка сегментирования" помогите!
Чтоб заработало - неплохо хотя б с управлением new/delete не лажать. Работа в отладочном коде краши в релизном - стандартное проявление undefined behaviour...
Когда пишете ответ, над окошком ряд иконок. Выделяете нужную часть текста и жмете правую, которая "Код". Можете отредактировать то сообщение хоть сейчас.
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
-
- Сообщения: 24
- ОС: linux Fedora Core
Re: "Ошибка сегментирования" помогите!
sergio писал(а): ↑18.09.2007 16:38
Чтоб заработало - неплохо хотя б с управлением new/delete не лажать. Работа в отладочном коде краши в релизном - стандартное проявление undefined behaviour...
Когда пишете ответ, над окошком ряд иконок. Выделяете нужную часть текста и жмете правую, которая "Код". Можете отредактировать то сообщение хоть сейчас.
Ребята я чательно все переделал и наладил проблемы с выделением памяти, вот новый вариант:
Код:
BOOL CFrameWork::LoadScanners()
{
char* _path = _pwd();
char* path = (char*)malloc(sizeof(char*)*(strlen(_path)+strlen("/SCANNERS")+1));
sprintf(path,"%s/SCANNERS",_path);
free(_path);
char *BASES = (char*)malloc(sizeof(char*)*(strlen(path)+15));
sprintf(BASES,"%s/bases.cav",path);
LARGE_INTEGER li;
li.HighPart=0;
li.LowPart=file_size(BASES);
if (!(m_hres = LoadModule(BASES,&li))) return false;
NAMING* naming;
DWORD naming_size;
char *names;
if (!(naming = (NAMING*)get_base(IDR_NAMING, &naming_size)) ||
!(names = (char*)get_base(IDR_MALWARE_FAMILIES)))
{
free(BASES);
return false;
}
free(BASES);
free(path);
_path = _pwd();
path = (char*)malloc(sizeof(char*)*(strlen(_path)+strlen("/SCANNERS")+1));
sprintf(path,"%s/SCANNERS",_path);
free(_path);
char *common = (char*)malloc(sizeof(char*)*(strlen(path)+15));
sprintf(common,"%s/common.cav",path);
li.HighPart=0;
li.LowPart=file_size(common);
LPVOID hmod;
if (!(hmod = LoadModule(common,&li)))
{
free(common);
return false;
}
free(common);
void (CDECL* SetNameInfo)(NAMING* , const char*, unsigned) =
(void (CDECL* )(NAMING* , const char*, unsigned ))GetProcAddr(hmod, 114);
if (!SetNameInfo)
{
UnloadModule(hmod);
return false;
}
SetNameInfo(naming, names, naming_size);
m_hcom = (LPVOID)hmod;
LoadScanners(path);
free(path);
return m_first != 0;
}
Но к сожалению всеровно падает там же

Скажите плз только одно: такие случаи типичны если программер налажал с new/delete?
-
- Сообщения: 436
- Статус: Интересующийся новичок
- ОС: Debian GNU/Linux 4 & 5
Re: "Ошибка сегментирования" помогите!
Ребят, вы поймите: вряд ли кто даже понял, что вы вообще делаете и в какой системе, и что там за мифический "загрузчик" вызывающий что-то из какой-то мифической библиотеки... обертка, умеющая работать в никсе со спертой из маздай длл-кой что ли?
Но код написан в том стиле, когда заставлять кого-то его читать-разбирать это... как бы, несколько нагло. Тем более, что проблему вы сформулировать не можете кроме как "оно падает". И ясно, что падать оно может по любым причинам, и ясно, что больше половины приведенного кода ничего интересного не содержит, кроме возможных ошибок.
Ну вот смотрите:
А в этой _pwd() у вас что? new[] или ?alloc? Там тоже проверили-переделали, или только здесь?
Вы уж выберите что-нибудь одно: или new/delete new[]/delete[] или ?alloc/free, а то ведь чокнитесь, зачем вам эта каша?
Размер выделяется неправильно - вы выделяете в 2/4/8 раз больше, чем предполагаете.
malloc(sizeof(char*)*(strlen(_path)+strlen("/SCANNERS")+1));
Эта же ерунда дальше повсюду...
В пути (не знаю уж путь ли это и куда) у вас прямые слэши должны быть или обратные? какая платформа-то блин,
куда эти пути передаются? В чужую библиотеку? а она какие хочет? А она с ними что делает? кто их перехватывает и правит на платформенные? Ну и т.д.
А вот здесь видно, что если ветвь if выполняется, то path не освобождается, а я в упор не вижу кому и куда она отдается для последующего освобождения...
Использование кучки alloc/free (а также непонятно чего, получаемого из сторонних вызовов) одновременно с несколькими точками выхода из функции - хороший метод сойти с ума и попасть в дурку...
Если программер лажает с управлением памятью, то типичны два случая:
- memory leaks и
-undefined behaviour
До сих пор не оглашено, какую библиотеку вы пытаетесь заставить работать и какое отношение виндознообразный код имеет к LinuxForum...

Но код написан в том стиле, когда заставлять кого-то его читать-разбирать это... как бы, несколько нагло. Тем более, что проблему вы сформулировать не можете кроме как "оно падает". И ясно, что падать оно может по любым причинам, и ясно, что больше половины приведенного кода ничего интересного не содержит, кроме возможных ошибок.
Ну вот смотрите:
evgeny22 писал(а): ↑18.09.2007 17:37Код: Выделить всё
BOOL CFrameWork::LoadScanners() { char* _path = _pwd(); char* path = (char*)malloc(sizeof(char*)*(strlen(_path)+strlen("/SCANNERS")+1)); sprintf(path,"%s/SCANNERS",_path); free(_path);
А в этой _pwd() у вас что? new[] или ?alloc? Там тоже проверили-переделали, или только здесь?
Вы уж выберите что-нибудь одно: или new/delete new[]/delete[] или ?alloc/free, а то ведь чокнитесь, зачем вам эта каша?
Размер выделяется неправильно - вы выделяете в 2/4/8 раз больше, чем предполагаете.
malloc(sizeof(char*)*(strlen(_path)+strlen("/SCANNERS")+1));
Эта же ерунда дальше повсюду...
В пути (не знаю уж путь ли это и куда) у вас прямые слэши должны быть или обратные? какая платформа-то блин,

Код: Выделить всё
if (!(naming = (NAMING*)get_base(IDR_NAMING, &naming_size)) || !(names = (char*)get_base(IDR_MALWARE_FAMILIES))) { free(BASES); return false; } free(BASES); free(path);
А вот здесь видно, что если ветвь if выполняется, то path не освобождается, а я в упор не вижу кому и куда она отдается для последующего освобождения...
Использование кучки alloc/free (а также непонятно чего, получаемого из сторонних вызовов) одновременно с несколькими точками выхода из функции - хороший метод сойти с ума и попасть в дурку...
Но к сожалению всеровно падает там же![]()
Скажите плз только одно: такие случаи типичны если программер налажал с new/delete?
Если программер лажает с управлением памятью, то типичны два случая:
- memory leaks и
-undefined behaviour

До сих пор не оглашено, какую библиотеку вы пытаетесь заставить работать и какое отношение виндознообразный код имеет к LinuxForum...
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
-
- Сообщения: 24
- ОС: linux Fedora Core
Re: "Ошибка сегментирования" помогите!
sergio писал(а): ↑18.09.2007 18:04Ребят, вы поймите: вряд ли кто даже понял, что вы вообще делаете и в какой системе, и что там за мифический "загрузчик" вызывающий что-то из какой-то мифической библиотеки... обертка, умеющая работать в никсе со спертой из маздай длл-кой что ли?![]()
Но код написан в том стиле, когда заставлять кого-то его читать-разбирать это... как бы, несколько нагло. Тем более, что проблему вы сформулировать не можете кроме как "оно падает". И ясно, что падать оно может по любым причинам, и ясно, что больше половины приведенного кода ничего интересного не содержит, кроме возможных ошибок.
Ну вот смотрите:
evgeny22 писал(а): ↑18.09.2007 17:37Код: Выделить всё
BOOL CFrameWork::LoadScanners() { char* _path = _pwd(); char* path = (char*)malloc(sizeof(char*)*(strlen(_path)+strlen("/SCANNERS")+1)); sprintf(path,"%s/SCANNERS",_path); free(_path);
А в этой _pwd() у вас что? new[] или ?alloc? Там тоже проверили-переделали, или только здесь?
Вы уж выберите что-нибудь одно: или new/delete new[]/delete[] или ?alloc/free, а то ведь чокнитесь, зачем вам эта каша?
Размер выделяется неправильно - вы выделяете в 2/4/8 раз больше, чем предполагаете.
malloc(sizeof(char*)*(strlen(_path)+strlen("/SCANNERS")+1));
Эта же ерунда дальше повсюду...
В пути (не знаю уж путь ли это и куда) у вас прямые слэши должны быть или обратные? какая платформа-то блин,куда эти пути передаются? В чужую библиотеку? а она какие хочет? А она с ними что делает? кто их перехватывает и правит на платформенные? Ну и т.д.
Код: Выделить всё
if (!(naming = (NAMING*)get_base(IDR_NAMING, &naming_size)) || !(names = (char*)get_base(IDR_MALWARE_FAMILIES))) { free(BASES); return false; } free(BASES); free(path);
А вот здесь видно, что если ветвь if выполняется, то path не освобождается, а я в упор не вижу кому и куда она отдается для последующего освобождения...
Использование кучки alloc/free (а также непонятно чего, получаемого из сторонних вызовов) одновременно с несколькими точками выхода из функции - хороший метод сойти с ума и попасть в дурку...
Но к сожалению всеровно падает там же![]()
Скажите плз только одно: такие случаи типичны если программер налажал с new/delete?
Если программер лажает с управлением памятью, то типичны два случая:
- memory leaks и
-undefined behaviour
![]()
До сих пор не оглашено, какую библиотеку вы пытаетесь заставить работать и какое отношение виндознообразный код имеет к LinuxForum...
Благодарю за высказывание.
Да, выразить проблему мне не удалось, надеелся что все прояснится через распросы)
Я не думал что моя просьба о помощи будет расценена как наглость, а наглость я больше всего не люблю в жизнь, поэтому заканчиваю данную тему. Просто опыта у меня не много под линухом и перепробовав неделю все советы решил спросить здесь у вас.
Всем спасибо, удачи!
-
- Сообщения: 636
- ОС: Gentoo GNU/Linux
Re: "Ошибка сегментирования" помогите!
если хочешь узнать где падает, пиши после каждой маловажной операции что-нибудь в лог или stderr.
хотя бы __FUNCTION__:__LINE__
проблему не решит, зато будет ясно откуда дровишки
хотя бы __FUNCTION__:__LINE__
проблему не решит, зато будет ясно откуда дровишки
все сказанное есть имхо...
-
- Сообщения: 24
- ОС: linux Fedora Core
Re: "Ошибка сегментирования" помогите!
Люди заработало!!!
Просто заменил все new/delete на alloc/free и заработало!
Огромное всем спасибо!!
Удачи
Просто заменил все new/delete на alloc/free и заработало!
Огромное всем спасибо!!
Удачи

-
- Сообщения: 1338
- Статус: We are all Kosh
- ОС: Fedora 10
Re: "Ошибка сегментирования" помогите!
Ну вот. А то наглость, наглость
Респект sergio

LightLang Team
-
- Сообщения: 436
- Статус: Интересующийся новичок
- ОС: Debian GNU/Linux 4 & 5
Re: "Ошибка сегментирования" помогите!
Ну будем надеяться, что причина была именно в этом.

На будущее: каждый кусок памяти размещается и удаляется соответствующим оператором/функцией. Их есть:
new - delete
new [] - delete []
?alloc - free
Путать их не стоит. Как вы догадываетесь, ?alloc находится в библиотеке си, а new - в библиотеке Си+, и даже если new реализован через вызов ?alloc или они оба тупо передают запрос системному вызову - то во-первых в Си+ оператор-нью может оказаться перегружен-переопределен для этого типа, во-вторых если оно у вас заработало на этой платформе - все может оказаться не так на другой. У new и new[] разный, скорее всего, принцип определения объема памяти для будущего делит.
С любой библиотекой: если она возвращает (получает) указатель (ссылку) на объект, должно быть специфицировано, кто этим объектом владеет и должен его удалять - библиотека или пользователь, не сидит ли он в статическом размещении (тогда его удалять низзя, и плюс к тому он будет разрушен, вероятно, следующим вызовом, плюс проблемы в многопоточных приложениях), и, если собственник объекта меняется, должно быть указано чем он был размещен/должен быть удален (если библиотека его отдала) или чем его вы должны были разместить (если библиотека его у вас принимает и удалять обещает самостоятельно).
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
-
- Сообщения: 24
- ОС: linux Fedora Core
Re: "Ошибка сегментирования" помогите!
sergio писал(а): ↑19.09.2007 11:32
Ну будем надеяться, что причина была именно в этом.![]()
На будущее: каждый кусок памяти размещается и удаляется соответствующим оператором/функцией. Их есть:
new - delete
new [] - delete []
?alloc - free
Путать их не стоит. Как вы догадываетесь, ?alloc находится в библиотеке си, а new - в библиотеке Си+, и даже если new реализован через вызов ?alloc или они оба тупо передают запрос системному вызову - то во-первых в Си+ оператор-нью может оказаться перегружен-переопределен для этого типа, во-вторых если оно у вас заработало на этой платформе - все может оказаться не так на другой. У new и new[] разный, скорее всего, принцип определения объема памяти для будущего делит.
С любой библиотекой: если она возвращает (получает) указатель (ссылку) на объект, должно быть специфицировано, кто этим объектом владеет и должен его удалять - библиотека или пользователь, не сидит ли он в статическом размещении (тогда его удалять низзя, и плюс к тому он будет разрушен, вероятно, следующим вызовом, плюс проблемы в многопоточных приложениях), и, если собственник объекта меняется, должно быть указано чем он был размещен/должен быть удален (если библиотека его отдала) или чем его вы должны были разместить (если библиотека его у вас принимает и удалять обещает самостоятельно).
Примного Вам благодарен!
И тут Вы угадали ситуацию: все работает под SUSELinux, но с той же ошибкой и на том же месте падает в Fedora Core 6... В силу моей неопытности программирования под **IX-ы я даже не могу догадываться почему на разных платформах с тем же ядром не работает все это дело..
-
- Сообщения: 436
- Статус: Интересующийся новичок
- ОС: Debian GNU/Linux 4 & 5
Re: "Ошибка сегментирования" помогите!
evgeny22 писал(а): ↑19.09.2007 11:50И тут Вы угадали ситуацию: все работает под SUSELinux, но с той же ошибкой и на том же месте падает в Fedora Core 6... В силу моей неопытности программирования под **IX-ы я даже не могу догадываться почему на разных платформах с тем же ядром не работает все это дело..
А, т.е. тут заработало, а в другой системе продолжает валиться?
Ну если сама сборка-установка в FC корректная, но видимо все то же undefined behaviour где-то осталось и дает себя знать. =) Это такая штука, которая есть просто фактор случайности, она может проявиться и на другой машине с Сюзи, и на той же самой в другой день недели, и вообще сидеть и никак себя не проявлять до момента сдачи заказчику.

В переводе на русский - это просто "ошибка, о которой соответствующий стандартам компилятор не обязан вам сообщать" (а попросту во многих случаях не имеет возможности ее отследить...)
Словом, фокусы с нью-аллок сами по себе могли и не вызывать никаких бед в вашем случае (а в другой день или на другой машине - вызвали бы), и их переделка, допустим, сдвинула что-то, изменила случайный фактор, и в другом месте undef beh. не привело ни каким критичным последствиям на этот раз, и программа заработала. Может быть и так.
Чтоб вам было не так тоскливо: согласно преданиям, на презентации посвящ. скорому выпуску Вин98, Билли Гейтс загрузил будущую мировую ОС, нажал кнопку "Пуск" и она зависла. Гений айти бизнеса быстро нашелся и сказал "Вот поэтому мы ее пока и не продаем".

Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
-
- Сообщения: 24
- ОС: linux Fedora Core
Re: "Ошибка сегментирования" помогите!
sergio писал(а): ↑19.09.2007 13:10evgeny22 писал(а): ↑19.09.2007 11:50И тут Вы угадали ситуацию: все работает под SUSELinux, но с той же ошибкой и на том же месте падает в Fedora Core 6... В силу моей неопытности программирования под **IX-ы я даже не могу догадываться почему на разных платформах с тем же ядром не работает все это дело..
А, т.е. тут заработало, а в другой системе продолжает валиться?
Ну если сама сборка-установка в FC корректная, но видимо все то же undefined behaviour где-то осталось и дает себя знать. =) Это такая штука, которая есть просто фактор случайности, она может проявиться и на другой машине с Сюзи, и на той же самой в другой день недели, и вообще сидеть и никак себя не проявлять до момента сдачи заказчику.![]()
В переводе на русский - это просто "ошибка, о которой соответствующий стандартам компилятор не обязан вам сообщать" (а попросту во многих случаях не имеет возможности ее отследить...)
Словом, фокусы с нью-аллок сами по себе могли и не вызывать никаких бед в вашем случае (а в другой день или на другой машине - вызвали бы), и их переделка, допустим, сдвинула что-то, изменила случайный фактор, и в другом месте undef beh. не привело ни каким критичным последствиям на этот раз, и программа заработала. Может быть и так.
Чтоб вам было не так тоскливо: согласно преданиям, на презентации посвящ. скорому выпуску Вин98, Билли Гейтс загрузил будущую мировую ОС, нажал кнопку "Пуск" и она зависла. Гений айти бизнеса быстро нашелся и сказал "Вот поэтому мы ее пока и не продаем".

Я немного запутался: а могу я например выделять память под строки через alloc/free, а объекты классов создавать и освобождать через new/delete? Или нужно использовать СТРОГО ТОЛЬКО одну из них во всем коде?
-
- Сообщения: 436
- Статус: Интересующийся новичок
- ОС: Debian GNU/Linux 4 & 5
Re: "Ошибка сегментирования" помогите!
evgeny22 писал(а): ↑19.09.2007 13:42Я очень устал от вечных ошибок "микромелких", поэтому и загарелся желанием заниматься **IX-ими платформами..
Я немного запутался: а могу я например выделять память под строки через alloc/free, а объекты классов создавать и освобождать через new/delete? Или нужно использовать СТРОГО ТОЛЬКО одну из них во всем коде?
Тогда хочу вас разочаровать: здесь ошибок не меньше.

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

По вопросу: объекты классов должны создаваться через new, поскольку нью-оператор не только размещает память (вызывая для этого operator new, который может быть переопределен), но и вызывает конструктор объекта. Если вы просто замените new на ?alloc, память будет размещена, но объект не создан (в принципе, его можно создать там потом вызовом new (pointer) ObjectType(args)), а вызов free освободит память но не вызовет деструктор (опять же, можно вызывать деструктор ручками до free), соотв-но, если объект в конструкторе сам размещает какую-то память (или открывает файлы), то при уничтожении без вызова деструктора эту память никто не освобдит (и другие беды).
Разумеется, вы можете размещать объекты нью, а память под строки выделять аллоками. Лишь бы вы точно знали, что у вас было размещено чем, и что чем, соотв-но, надо удалять. И не путать delete с delete[]. И следить что нужно использовать если при вызовах чужого/библиотечного кода происходит передаче собственности.
Если вы одни сишные псевдо-строки будете размещать нью[], а другие аллок, но не запутаться и не ошибиться вам будет непросто.

Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
-
- Сообщения: 24
- ОС: linux Fedora Core
Re: "Ошибка сегментирования" помогите!
sergio писал(а): ↑19.09.2007 14:07evgeny22 писал(а): ↑19.09.2007 13:42Я очень устал от вечных ошибок "микромелких", поэтому и загарелся желанием заниматься **IX-ими платформами..
Я немного запутался: а могу я например выделять память под строки через alloc/free, а объекты классов создавать и освобождать через new/delete? Или нужно использовать СТРОГО ТОЛЬКО одну из них во всем коде?
Тогда хочу вас разочаровать: здесь ошибок не меньше.![]()
Различие в другом: там кривизна заложенная в систему (прежде всего - изначально) неисправима, созданная какой-либо крупной компанией - неисправима силами пользователя(лей), а здесь неудачные решения погибают в конкурентной борьбе или разбираются конкурентами на органы и запчасти.Поэтому и бардак такой и пакетов так много и даже десктопов.
По вопросу: объекты классов должны создаваться через new, поскольку нью-оператор не только размещает память (вызывая для этого operator new, который может быть переопределен), но и вызывает конструктор объекта. Если вы просто замените new на ?alloc, память будет размещена, но объект не создан (в принципе, его можно создать там потом вызовом new (pointer) ObjectType(args)), а вызов free освободит память но не вызовет деструктор (опять же, можно вызывать деструктор ручками до free), соотв-но, если объект в конструкторе сам размещает какую-то память (или открывает файлы), то при уничтожении без вызова деструктора эту память никто не освобдит (и другие беды).
Разумеется, вы можете размещать объекты нью, а память под строки выделять аллоками. Лишь бы вы точно знали, что у вас было размещено чем, и что чем, соотв-но, надо удалять. И не путать delete с delete[]. И следить что нужно использовать если при вызовах чужого/библиотечного кода происходит передаче собственности.
Если вы одни сишные псевдо-строки будете размещать нью[], а другие аллок, но не запутаться и не ошибиться вам будет непросто.
Еще раз благодарю вас за все!
Пока вроде вопросы закончились

-
- Сообщения: 604
- Статус: core dumped
- ОС: Plan 9
Re: "Ошибка сегментирования" помогите!
evgeny22 писал(а): ↑19.09.2007 13:42Я очень устал от вечных ошибок "микромелких", поэтому и загарелся желанием заниматься **IX-ими платформами..
Я немного запутался: а могу я например выделять память под строки через alloc/free, а объекты классов создавать и освобождать через new/delete? Или нужно использовать СТРОГО ТОЛЬКО одну из них во всем коде?
Помоему для ого чтобы понять, как создавать объект, нужно понять что происходит при вызове new и как объект создается в C++, и что происходит при вызове alloc, тоесть просто почитать книгу по C++ например. Кстати, при вызове new также вызывается alloc, только при этом производятся еще некторые действия. И от платформы это совершенно не зависит.
Блог
--------------------
GCS/M/MU/P/IT/E d- s: a- C++(+++) UBL++ P->-- L+++$ E- W+++$ N* o? K? w>--
O M-@ V- PS@ PE+ Y+ PGP+ t 5 X R* tv-->- b++ DI? D>+ G e+(++) h--- r+ y++
--------------------
GCS/M/MU/P/IT/E d- s: a- C++(+++) UBL++ P->-- L+++$ E- W+++$ N* o? K? w>--
O M-@ V- PS@ PE+ Y+ PGP+ t 5 X R* tv-->- b++ DI? D>+ G e+(++) h--- r+ y++
-
- Сообщения: 3339
- ОС: Slackware 12.2, ArchLinux 64
Re: "Ошибка сегментирования" помогите!
Я не претендую на то, чтобы быть шибко умным, но вообще говоря, смешивать кислое с пресным бывает накладно.
В C++ память выделяется оператором new и освобождается оператором delete. Точка. Никаких malloc/free в C++ нет.
В C++ память выделяется оператором new и освобождается оператором delete. Точка. Никаких malloc/free в C++ нет.
-
- Сообщения: 24
- ОС: linux Fedora Core
Re: "Ошибка сегментирования" помогите!
Люди, извиняйте если это наглость, но теперь я не могу понять почему после обработки сигнала молча перестает работать прога.
Я регестрирую сигнал:
обявляю для него обработчик:
Есть у меня функция для удобной отправки сигналов:
ну и собственно посылаю:
Сигнал отправляется и даже получается и выводится строка, но вот ф-ия SendSignal уже дальше не работает, т.е.: не срабатывает следующий код:
Кто-нибудь может пожалуйста взглянуть и тыкнуть что я делаю противозаконого? Опять же - в отладчике все пашет...
Еще раз извеняйте за беспокойство
Я регестрирую сигнал:
Код:
#define SIG_BEGIN_SCAN SIGRTMIN+3
......
......
struct sigaction begin_act;
begin_act.sa_sigaction = begin_scan_handler;
begin_act.sa_flags = SA_SIGINFO;
sigaction(SIG_BEGIN_SCAN, &begin_act, NULL);
обявляю для него обработчик:
Код:
void begin_scan_handler(int signo, siginfo_t *si, void *context)
{cout<<"begin scan...\n";
if(signo == SIG_BEGIN_SCAN) {
if(si->si_code == SI_QUEUE) {
char* fullName = (char*)si->si_value.sival_ptr;
showmsg(fullName);
free(fullName);
}
}
cout<<"begin scan end...\n";
}
Есть у меня функция для удобной отправки сигналов:
Код:
void CFrameWork::SendSignal(int pid, int signo, void* data)
{
printf("In SendSignal:\n");
sigval val;
val.sival_ptr = data;
sigset_t mask;
sigset_t oldMask;
sigemptyset(&mask);
sigaddset(&mask, signo);
printf("before sigprocmask()\n");
sigprocmask(SIG_BLOCK,&mask, &oldMask);
if(data)
{
printf("sigqueue()\n");
sigqueue(pid, signo, val);
}
else
{
printf("kill()\n");
kill(pid,signo);
}
printf("sigprocmask()\n");
sigprocmask(SIG_SETMASK, &oldMask, NULL);
printf("End SendSignal\n");
}
ну и собственно посылаю:
Код:
char* fn = (char*)malloc(100);
strcpy(fn,"just a string....");
SendSignal(getpid(),SIG_BEGIN_SCAN,fn);
Сигнал отправляется и даже получается и выводится строка, но вот ф-ия SendSignal уже дальше не работает, т.е.: не срабатывает следующий код:
Код:
printf("sigprocmask()\n");
Кто-нибудь может пожалуйста взглянуть и тыкнуть что я делаю противозаконого? Опять же - в отладчике все пашет...
Еще раз извеняйте за беспокойство
-
- Сообщения: 24
- ОС: linux Fedora Core
-
- Сообщения: 436
- Статус: Интересующийся новичок
- ОС: Debian GNU/Linux 4 & 5
Re: "Ошибка сегментирования" помогите!
Типо уточнение.
Сомневаюсь, что оговорено, что в реализации (даже стандартной) new обязан быть вызов ?alloc. Кроме того, new может оказаться переопределен и никаких аллоков не содержать. Но в любом случае, здесь речь шла просто о негодности кода, где char[] размещенный нью[] уничтожается delete или фри.
Uncle_Theodore писал(а): ↑19.09.2007 15:29Я не претендую на то, чтобы быть шибко умным, но вообще говоря, смешивать кислое с пресным бывает накладно.
В C++ память выделяется оператором new и освобождается оператором delete. Точка. Никаких malloc/free в C++ нет.
Ну, официальная точка кажется такова: С++ включает всю Си библиотеку (в неймспейсе стд, хотя и это уже почти отменили

В целом, совершенно разделяю точку зрения на счет кисло-пресного, и возиться со смешанным кодом может быть оч неприятно, равно как и со стилем "си с классами", к которому близок, например MFC. Кроме того, связка языков вообще сложная, противоречивая и оч проблемная - в стандарте ряд вещей просто не решены, или заданы так, что реализовать их невозможно или это пахнет извратом.
К сожалению, c'est la vie. Тут уж я не знаю, что человек делает, и от какого кода/инфраструктуры зависит...
Автору темы:
В библиотеке си большая часть функций нейтральны относительно схемы управления памятью и хотят от вас указатель на все готовое, но некоторые - нет, напр. str?dup:
Function: char * strdup (const char *s)
This function copies the null-terminated string s into a newly allocated string. The string is allocated using malloc; see Unconstrained Allocation. If malloc cannot allocate space for the new string, strdup returns a null pointer. Otherwise it returns a pointer to the new string.
Будьте внимательны. =)
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
-
- Сообщения: 604
- Статус: core dumped
- ОС: Plan 9
Re: "Ошибка сегментирования" помогите!
sergio писал(а): ↑19.09.2007 15:48
Типо уточнение.
Сомневаюсь, что оговорено, что в реализации (даже стандартной) new обязан быть вызов ?alloc. Кроме того, new может оказаться переопределен и никаких аллоков не содержать. Но в любом случае, здесь речь шла просто о негодности кода, где char[] размещенный нью[] уничтожается delete или фри.
Безусловно может не содержать вызов ?alloc и в стандарте этого естественно нет. Все зависит от реализации. Знаю что изначально это было реализовано, помоему через malloc.
Идея моего поста была в том что неплохо бы разобраться в механизмах создания объектов в С++, тогда такие вопросы сами собой отпадут

Блог
--------------------
GCS/M/MU/P/IT/E d- s: a- C++(+++) UBL++ P->-- L+++$ E- W+++$ N* o? K? w>--
O M-@ V- PS@ PE+ Y+ PGP+ t 5 X R* tv-->- b++ DI? D>+ G e+(++) h--- r+ y++
--------------------
GCS/M/MU/P/IT/E d- s: a- C++(+++) UBL++ P->-- L+++$ E- W+++$ N* o? K? w>--
O M-@ V- PS@ PE+ Y+ PGP+ t 5 X R* tv-->- b++ DI? D>+ G e+(++) h--- r+ y++
-
- Сообщения: 436
- Статус: Интересующийся новичок
- ОС: Debian GNU/Linux 4 & 5
Re: "Ошибка сегментирования" помогите!
Мысль здравая, нет сомнений.
Злая хохма в том, что как у К.и Ричи нет ни намека на управление памятью (хаха!), так и у Страуструпа эта тема на удивление спокойно обойдена.


2 Автор: посмотрите у Мейерса...
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
-
- Сообщения: 2910
Re: "Ошибка сегментирования" помогите!
Так, если чел в срочном порядке не показывает всю детальную инфу, прикрываю тему нафик, ибо код на самом деле оч похож на оффтоп. Такие вот шедевральные проги обычно пишут в венде преподы универские.
-
- Сообщения: 604
- Статус: core dumped
- ОС: Plan 9
Re: "Ошибка сегментирования" помогите!
sergio писал(а): ↑19.09.2007 19:48
Мысль здравая, нет сомнений.
Злая хохма в том, что как у К.и Ричи нет ни намека на управление памятью (хаха!), так и у Страуструпа эта тема на удивление спокойно обойдена.И человеческих разъяснений что это за new new[] new() и operator new по-моему просто не было.
2 Автор: посмотрите у Мейерса...
Ну надо во-первых правельные книги читать, где написано. Во-вторых, если ползуешься чем то неплохо бы разобраться, отмазки типа - этого нет в книге по C/C++ которую я читал, катят может быть для препода в институте, но не как не для себя. По C++ могу посоветовать Ст. Липмана - у него все очень подробно разжевывается.
Прошу прощения за флуд

Блог
--------------------
GCS/M/MU/P/IT/E d- s: a- C++(+++) UBL++ P->-- L+++$ E- W+++$ N* o? K? w>--
O M-@ V- PS@ PE+ Y+ PGP+ t 5 X R* tv-->- b++ DI? D>+ G e+(++) h--- r+ y++
--------------------
GCS/M/MU/P/IT/E d- s: a- C++(+++) UBL++ P->-- L+++$ E- W+++$ N* o? K? w>--
O M-@ V- PS@ PE+ Y+ PGP+ t 5 X R* tv-->- b++ DI? D>+ G e+(++) h--- r+ y++