"Ошибка сегментирования" помогите! (Программа нормально работает в отладчике, но падает без него)

Модератор: Модераторы разделов

evgeny22
Сообщения: 24
ОС: linux Fedora Core

"Ошибка сегментирования" помогите!

Сообщение evgeny22 »

Помогите кто-нибудь пожалуйста!
Я никогда еще с таким не встречался:

Однопаточная программа, при выполнении в отладчике работает нормально, а вот когда запускаю без него, то сразу падает с ошибкой "ошибка сегментирования". Падает при вызове функции, притом, в отладчике наблюдается, что функция вызывается нормально и правильно отрабатывает, а вот без отладчика на ней же валится. Подскажите пожалуйста хоть что-нибудь...

Заранее очень благодарен.[font="Arial Black"][font]
Спасибо сказали:
Аватара пользователя
BlackStar
Сообщения: 1338
Статус: We are all Kosh
ОС: Fedora 10

Re: "Ошибка сегментирования" помогите!

Сообщение BlackStar »

Код программы в студию!
LightLang Team
Спасибо сказали:
evgeny22
Сообщения: 24
ОС: linux Fedora Core

Re: "Ошибка сегментирования" помогите!

Сообщение evgeny22 »

BlackStar писал(а):
18.09.2007 15:19
Код программы в студию!



Спасибо!

Код - не проблема, проблема в том, что не знаю даже с чего начать. Дела обстоят так: есть 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;
}

Т. е.: она не делает ничего криминального, просто инициализирует глобальные переменные... вот на ней и валится...
Спасибо сказали:
d_n_k
Сообщения: 636
ОС: Gentoo GNU/Linux

Re: "Ошибка сегментирования" помогите!

Сообщение d_n_k »

Код: Выделить всё

char* path = _pwd();
strcat(path,"/SCANNERS");

память кто будет выделять под удлинение строки?

именование переменных говорит о коде под оффтопик. имхо, не должен тут обсуждаться

код не форматирован, читабельность -10
все сказанное есть имхо...
Спасибо сказали:
sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: "Ошибка сегментирования" помогите!

Сообщение sergio »

evgeny22 писал(а):
18.09.2007 15:36
BOOL CFrameWork::LoadScanners()
{
char* path = _pwd();
strcat(path,"/SCANNERS");

Как вы понимаете, я могу только догадываться, что вы знаете, что в 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
Спасибо сказали:
evgeny22
Сообщения: 24
ОС: linux Fedora Core

Re: "Ошибка сегментирования" помогите!

Сообщение evgeny22 »

sergio писал(а):
18.09.2007 16:18
evgeny22 писал(а):
18.09.2007 15:36
BOOL CFrameWork::LoadScanners()
{
char* path = _pwd();
strcat(path,"/SCANNERS");

Как вы понимаете, я могу только догадываться, что вы знаете, что в 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.: извиняйте за нечитабильность кода, я первый раз тут))
Спасибо сказали:
sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: "Ошибка сегментирования" помогите!

Сообщение sergio »

evgeny22 писал(а):
18.09.2007 16:32
согласен на все 100%, что такой подход является больше чем неправельным, но на данный момент мне нужно, чтоб срочно заработала основа, потом я обязательно поправлю все эти глупые моменты.

P.S.: извиняйте за нечитабильность кода, я первый раз тут))

Чтоб заработало - неплохо хотя б с управлением 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
Спасибо сказали:
evgeny22
Сообщения: 24
ОС: linux Fedora Core

Re: "Ошибка сегментирования" помогите!

Сообщение evgeny22 »

sergio писал(а):
18.09.2007 16:38
evgeny22 писал(а):
18.09.2007 16:32
согласен на все 100%, что такой подход является больше чем неправельным, но на данный момент мне нужно, чтоб срочно заработала основа, потом я обязательно поправлю все эти глупые моменты.

P.S.: извиняйте за нечитабильность кода, я первый раз тут))

Чтоб заработало - неплохо хотя б с управлением 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; }


Но к сожалению всеровно падает там же :mellow:
Скажите плз только одно: такие случаи типичны если программер налажал с new/delete?
Спасибо сказали:
sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: "Ошибка сегментирования" помогите!

Сообщение sergio »

Ребят, вы поймите: вряд ли кто даже понял, что вы вообще делаете и в какой системе, и что там за мифический "загрузчик" вызывающий что-то из какой-то мифической библиотеки... обертка, умеющая работать в никсе со спертой из маздай длл-кой что ли? :rolleyes:

Но код написан в том стиле, когда заставлять кого-то его читать-разбирать это... как бы, несколько нагло. Тем более, что проблему вы сформулировать не можете кроме как "оно падает". И ясно, что падать оно может по любым причинам, и ясно, что больше половины приведенного кода ничего интересного не содержит, кроме возможных ошибок.

Ну вот смотрите:

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));
Эта же ерунда дальше повсюду...
В пути (не знаю уж путь ли это и куда) у вас прямые слэши должны быть или обратные? какая платформа-то блин, :D куда эти пути передаются? В чужую библиотеку? а она какие хочет? А она с ними что делает? кто их перехватывает и правит на платформенные? Ну и т.д.

Код: Выделить всё

    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 (а также непонятно чего, получаемого из сторонних вызовов) одновременно с несколькими точками выхода из функции - хороший метод сойти с ума и попасть в дурку...

Но к сожалению всеровно падает там же :mellow:
Скажите плз только одно: такие случаи типичны если программер налажал с 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
Спасибо сказали:
evgeny22
Сообщения: 24
ОС: linux Fedora Core

Re: "Ошибка сегментирования" помогите!

Сообщение evgeny22 »

sergio писал(а):
18.09.2007 18:04
Ребят, вы поймите: вряд ли кто даже понял, что вы вообще делаете и в какой системе, и что там за мифический "загрузчик" вызывающий что-то из какой-то мифической библиотеки... обертка, умеющая работать в никсе со спертой из маздай длл-кой что ли? :rolleyes:

Но код написан в том стиле, когда заставлять кого-то его читать-разбирать это... как бы, несколько нагло. Тем более, что проблему вы сформулировать не можете кроме как "оно падает". И ясно, что падать оно может по любым причинам, и ясно, что больше половины приведенного кода ничего интересного не содержит, кроме возможных ошибок.

Ну вот смотрите:

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));
Эта же ерунда дальше повсюду...
В пути (не знаю уж путь ли это и куда) у вас прямые слэши должны быть или обратные? какая платформа-то блин, :D куда эти пути передаются? В чужую библиотеку? а она какие хочет? А она с ними что делает? кто их перехватывает и правит на платформенные? Ну и т.д.

Код: Выделить всё

    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 (а также непонятно чего, получаемого из сторонних вызовов) одновременно с несколькими точками выхода из функции - хороший метод сойти с ума и попасть в дурку...

Но к сожалению всеровно падает там же :mellow:
Скажите плз только одно: такие случаи типичны если программер налажал с new/delete?

Если программер лажает с управлением памятью, то типичны два случая:
- memory leaks и
-undefined behaviour
;)
До сих пор не оглашено, какую библиотеку вы пытаетесь заставить работать и какое отношение виндознообразный код имеет к LinuxForum...



Благодарю за высказывание.
Да, выразить проблему мне не удалось, надеелся что все прояснится через распросы)
Я не думал что моя просьба о помощи будет расценена как наглость, а наглость я больше всего не люблю в жизнь, поэтому заканчиваю данную тему. Просто опыта у меня не много под линухом и перепробовав неделю все советы решил спросить здесь у вас.

Всем спасибо, удачи!
Спасибо сказали:
d_n_k
Сообщения: 636
ОС: Gentoo GNU/Linux

Re: "Ошибка сегментирования" помогите!

Сообщение d_n_k »

если хочешь узнать где падает, пиши после каждой маловажной операции что-нибудь в лог или stderr.
хотя бы __FUNCTION__:__LINE__

проблему не решит, зато будет ясно откуда дровишки
все сказанное есть имхо...
Спасибо сказали:
evgeny22
Сообщения: 24
ОС: linux Fedora Core

Re: "Ошибка сегментирования" помогите!

Сообщение evgeny22 »

Люди заработало!!!
Просто заменил все new/delete на alloc/free и заработало!
Огромное всем спасибо!!

Удачи;)
Спасибо сказали:
Аватара пользователя
BlackStar
Сообщения: 1338
Статус: We are all Kosh
ОС: Fedora 10

Re: "Ошибка сегментирования" помогите!

Сообщение BlackStar »

Ну вот. А то наглость, наглость :) Респект sergio
LightLang Team
Спасибо сказали:
sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: "Ошибка сегментирования" помогите!

Сообщение sergio »

evgeny22 писал(а):
19.09.2007 01:20
Просто заменил все new/delete на alloc/free и заработало!

Ну будем надеяться, что причина была именно в этом. :happy:
На будущее: каждый кусок памяти размещается и удаляется соответствующим оператором/функцией. Их есть:
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
Спасибо сказали:
evgeny22
Сообщения: 24
ОС: linux Fedora Core

Re: "Ошибка сегментирования" помогите!

Сообщение evgeny22 »

sergio писал(а):
19.09.2007 11:32
evgeny22 писал(а):
19.09.2007 01:20
Просто заменил все new/delete на alloc/free и заработало!

Ну будем надеяться, что причина была именно в этом. :happy:
На будущее: каждый кусок памяти размещается и удаляется соответствующим оператором/функцией. Их есть:
new - delete
new [] - delete []
?alloc - free
Путать их не стоит. Как вы догадываетесь, ?alloc находится в библиотеке си, а new - в библиотеке Си+, и даже если new реализован через вызов ?alloc или они оба тупо передают запрос системному вызову - то во-первых в Си+ оператор-нью может оказаться перегружен-переопределен для этого типа, во-вторых если оно у вас заработало на этой платформе - все может оказаться не так на другой. У new и new[] разный, скорее всего, принцип определения объема памяти для будущего делит.
С любой библиотекой: если она возвращает (получает) указатель (ссылку) на объект, должно быть специфицировано, кто этим объектом владеет и должен его удалять - библиотека или пользователь, не сидит ли он в статическом размещении (тогда его удалять низзя, и плюс к тому он будет разрушен, вероятно, следующим вызовом, плюс проблемы в многопоточных приложениях), и, если собственник объекта меняется, должно быть указано чем он был размещен/должен быть удален (если библиотека его отдала) или чем его вы должны были разместить (если библиотека его у вас принимает и удалять обещает самостоятельно).


Примного Вам благодарен!
И тут Вы угадали ситуацию: все работает под SUSELinux, но с той же ошибкой и на том же месте падает в Fedora Core 6... В силу моей неопытности программирования под **IX-ы я даже не могу догадываться почему на разных платформах с тем же ядром не работает все это дело..
Спасибо сказали:
sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: "Ошибка сегментирования" помогите!

Сообщение sergio »

evgeny22 писал(а):
19.09.2007 11:50
И тут Вы угадали ситуацию: все работает под SUSELinux, но с той же ошибкой и на том же месте падает в Fedora Core 6... В силу моей неопытности программирования под **IX-ы я даже не могу догадываться почему на разных платформах с тем же ядром не работает все это дело..

А, т.е. тут заработало, а в другой системе продолжает валиться?
Ну если сама сборка-установка в FC корректная, но видимо все то же undefined behaviour где-то осталось и дает себя знать. =) Это такая штука, которая есть просто фактор случайности, она может проявиться и на другой машине с Сюзи, и на той же самой в другой день недели, и вообще сидеть и никак себя не проявлять до момента сдачи заказчику. :happy:
В переводе на русский - это просто "ошибка, о которой соответствующий стандартам компилятор не обязан вам сообщать" (а попросту во многих случаях не имеет возможности ее отследить...)
Словом, фокусы с нью-аллок сами по себе могли и не вызывать никаких бед в вашем случае (а в другой день или на другой машине - вызвали бы), и их переделка, допустим, сдвинула что-то, изменила случайный фактор, и в другом месте undef beh. не привело ни каким критичным последствиям на этот раз, и программа заработала. Может быть и так.

Чтоб вам было не так тоскливо: согласно преданиям, на презентации посвящ. скорому выпуску Вин98, Билли Гейтс загрузил будущую мировую ОС, нажал кнопку "Пуск" и она зависла. Гений айти бизнеса быстро нашелся и сказал "Вот поэтому мы ее пока и не продаем". :happy:
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Спасибо сказали:
evgeny22
Сообщения: 24
ОС: linux Fedora Core

Re: "Ошибка сегментирования" помогите!

Сообщение evgeny22 »

sergio писал(а):
19.09.2007 13:10
evgeny22 писал(а):
19.09.2007 11:50
И тут Вы угадали ситуацию: все работает под SUSELinux, но с той же ошибкой и на том же месте падает в Fedora Core 6... В силу моей неопытности программирования под **IX-ы я даже не могу догадываться почему на разных платформах с тем же ядром не работает все это дело..

А, т.е. тут заработало, а в другой системе продолжает валиться?
Ну если сама сборка-установка в FC корректная, но видимо все то же undefined behaviour где-то осталось и дает себя знать. =) Это такая штука, которая есть просто фактор случайности, она может проявиться и на другой машине с Сюзи, и на той же самой в другой день недели, и вообще сидеть и никак себя не проявлять до момента сдачи заказчику. :happy:
В переводе на русский - это просто "ошибка, о которой соответствующий стандартам компилятор не обязан вам сообщать" (а попросту во многих случаях не имеет возможности ее отследить...)
Словом, фокусы с нью-аллок сами по себе могли и не вызывать никаких бед в вашем случае (а в другой день или на другой машине - вызвали бы), и их переделка, допустим, сдвинула что-то, изменила случайный фактор, и в другом месте undef beh. не привело ни каким критичным последствиям на этот раз, и программа заработала. Может быть и так.

Чтоб вам было не так тоскливо: согласно преданиям, на презентации посвящ. скорому выпуску Вин98, Билли Гейтс загрузил будущую мировую ОС, нажал кнопку "Пуск" и она зависла. Гений айти бизнеса быстро нашелся и сказал "Вот поэтому мы ее пока и не продаем". :happy:



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

Re: "Ошибка сегментирования" помогите!

Сообщение sergio »

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

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

По вопросу: объекты классов должны создаваться через 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
Спасибо сказали:
evgeny22
Сообщения: 24
ОС: linux Fedora Core

Re: "Ошибка сегментирования" помогите!

Сообщение evgeny22 »

sergio писал(а):
19.09.2007 14:07
evgeny22 писал(а):
19.09.2007 13:42
:rolleyes: Я очень устал от вечных ошибок "микромелких", поэтому и загарелся желанием заниматься **IX-ими платформами..
Я немного запутался: а могу я например выделять память под строки через alloc/free, а объекты классов создавать и освобождать через new/delete? Или нужно использовать СТРОГО ТОЛЬКО одну из них во всем коде?

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

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



Еще раз благодарю вас за все!
Пока вроде вопросы закончились:)
Спасибо сказали:
Аватара пользователя
Sparky
Сообщения: 604
Статус: core dumped
ОС: Plan 9

Re: "Ошибка сегментирования" помогите!

Сообщение Sparky »

evgeny22 писал(а):
19.09.2007 13:42
:rolleyes: Я очень устал от вечных ошибок "микромелких", поэтому и загарелся желанием заниматься **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++
Спасибо сказали:
Аватара пользователя
Uncle_Theodore
Сообщения: 3339
ОС: Slackware 12.2, ArchLinux 64

Re: "Ошибка сегментирования" помогите!

Сообщение Uncle_Theodore »

Я не претендую на то, чтобы быть шибко умным, но вообще говоря, смешивать кислое с пресным бывает накладно.
В C++ память выделяется оператором new и освобождается оператором delete. Точка. Никаких malloc/free в C++ нет.
Спасибо сказали:
evgeny22
Сообщения: 24
ОС: linux Fedora Core

Re: "Ошибка сегментирования" помогите!

Сообщение evgeny22 »

Люди, извиняйте если это наглость, но теперь я не могу понять почему после обработки сигнала молча перестает работать прога.

Я регестрирую сигнал:

Код:

#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");


Кто-нибудь может пожалуйста взглянуть и тыкнуть что я делаю противозаконого? Опять же - в отладчике все пашет...
Еще раз извеняйте за беспокойство
Спасибо сказали:
evgeny22
Сообщения: 24
ОС: linux Fedora Core

Re: "Ошибка сегментирования" помогите!

Сообщение evgeny22 »

evgeny22 писал(а):
19.09.2007 15:34
Кто-нибудь может пожалуйста взглянуть и тыкнуть что я делаю противозаконого? Опять же - в отладчике все пашет...
Еще раз извеняйте за беспокойство


Забыл сказать: отправка сигнала осуществляется в отдельном потоке
Спасибо сказали:
sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: "Ошибка сегментирования" помогите!

Сообщение sergio »

Sparky писал(а):
19.09.2007 15:23
Кстати, при вызове new также вызывается alloc, только при этом производятся еще некторые действия. И от платформы это совершенно не зависит.

Типо уточнение.
Сомневаюсь, что оговорено, что в реализации (даже стандартной) new обязан быть вызов ?alloc. Кроме того, new может оказаться переопределен и никаких аллоков не содержать. Но в любом случае, здесь речь шла просто о негодности кода, где char[] размещенный нью[] уничтожается delete или фри.

Uncle_Theodore писал(а):
19.09.2007 15:29
Я не претендую на то, чтобы быть шибко умным, но вообще говоря, смешивать кислое с пресным бывает накладно.
В C++ память выделяется оператором new и освобождается оператором delete. Точка. Никаких malloc/free в C++ нет.


Ну, официальная точка кажется такова: С++ включает всю Си библиотеку (в неймспейсе стд, хотя и это уже почти отменили :angry: ).
В целом, совершенно разделяю точку зрения на счет кисло-пресного, и возиться со смешанным кодом может быть оч неприятно, равно как и со стилем "си с классами", к которому близок, например 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
Спасибо сказали:
Аватара пользователя
Sparky
Сообщения: 604
Статус: core dumped
ОС: Plan 9

Re: "Ошибка сегментирования" помогите!

Сообщение Sparky »

sergio писал(а):
19.09.2007 15:48
Sparky писал(а):
19.09.2007 15:23
Кстати, при вызове new также вызывается alloc, только при этом производятся еще некторые действия. И от платформы это совершенно не зависит.

Типо уточнение.
Сомневаюсь, что оговорено, что в реализации (даже стандартной) 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++
Спасибо сказали:
sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: "Ошибка сегментирования" помогите!

Сообщение sergio »

Sparky писал(а):
19.09.2007 17:20
Идея моего поста была в том что неплохо бы разобраться в механизмах создания объектов в С++, тогда такие вопросы сами собой отпадут :)


Мысль здравая, нет сомнений.
Злая хохма в том, что как у К.и Ричи нет ни намека на управление памятью (хаха!), так и у Страуструпа эта тема на удивление спокойно обойдена. :D И человеческих разъяснений что это за new new[] new() и operator new по-моему просто не было. :D
2 Автор: посмотрите у Мейерса...
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Спасибо сказали:
Аватара пользователя
Liksys
Сообщения: 2910

Re: "Ошибка сегментирования" помогите!

Сообщение Liksys »

Так, если чел в срочном порядке не показывает всю детальную инфу, прикрываю тему нафик, ибо код на самом деле оч похож на оффтоп. Такие вот шедевральные проги обычно пишут в венде преподы универские.
Спасибо сказали:
Аватара пользователя
Sparky
Сообщения: 604
Статус: core dumped
ОС: Plan 9

Re: "Ошибка сегментирования" помогите!

Сообщение Sparky »

sergio писал(а):
19.09.2007 19:48
Sparky писал(а):
19.09.2007 17:20
Идея моего поста была в том что неплохо бы разобраться в механизмах создания объектов в С++, тогда такие вопросы сами собой отпадут :)


Мысль здравая, нет сомнений.
Злая хохма в том, что как у К.и Ричи нет ни намека на управление памятью (хаха!), так и у Страуструпа эта тема на удивление спокойно обойдена. :D И человеческих разъяснений что это за new new[] new() и operator new по-моему просто не было. :D
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++
Спасибо сказали: