Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Программирование под Unix/Linux > Ошибка malloc(): memory coorruption


Автор: Zerstroer 24.2.2011, 14:58
Здравствуйте, при работе программы возникает такая вот ошибка:
Код

*** glibc detected *** /home/evgen/NetBeansProjects/umbus/dist/Debug/GNU-Linux-x86/umbus: malloc(): memory corruption: 0x08cb22c8 ***
======= Backtrace: =========
/lib/i686/cmov/libc.so.6(+0x6b281)[0xb74a0281]
/lib/i686/cmov/libc.so.6(+0x6e085)[0xb74a3085]
/lib/i686/cmov/libc.so.6(__libc_malloc+0x5c)[0xb74a4c8c]
/usr/lib/libstdc++.so.6(_Znwj+0x27)[0xb767cba7]
/usr/lib/libstdc++.so.6(_ZNSs4_Rep9_S_createEjjRKSaIcE+0x66)[0xb7656796]
/usr/lib/libstdc++.so.6(+0x98494)[0xb7657494]
/usr/lib/libstdc++.so.6(_ZNSsC1EPKcRKSaIcE+0x46)[0xb7657686]
/home/evgen/NetBeansProjects/umbus/dist/Debug/GNU-Linux-x86/umbus[0x804f764]
/home/evgen/NetBeansProjects/umbus/dist/Debug/GNU-Linux-x86/umbus[0x804bfc4]
/home/evgen/NetBeansProjects/umbus/dist/Debug/GNU-Linux-x86/umbus[0x804c973]
/lib/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xb744bc76]
/home/evgen/NetBeansProjects/umbus/dist/Debug/GNU-Linux-x86/umbus[0x8049ca1]
======= Memory map: ========
08048000-08053000 r-xp 00000000 08:07 4459146    /home/evgen/NetBeansProjects/umbus/dist/Debug/GNU-Linux-x86/umbus
08053000-08054000 rwxp 0000a000 08:07 4459146    /home/evgen/NetBeansProjects/umbus/dist/Debug/GNU-Linux-x86/umbus
08c95000-08cb6000 rwxp 00000000 00:00 0          [heap]
b7200000-b7221000 rwxp 00000000 00:00 0 
b7221000-b7300000 ---p 00000000 00:00 0 
и т.д.


Путем отладки выяснил, что возникает она при вызове функции приблизительного следующего вида (лишний код я опустил для конкретики).
Код

string MyF(char* input){
   string s;
   s = (string)input;
/*операции над s*/
  return s;
}


Конкретно, строка, на которой ошибка возникает: 
 
Код

s = (string)input;

Возникает ошибка при втором или третьем обращении к данной функции, что именно меня и смущает. Прошу помочь разобраться. С понятием указателя (char*) знаком, менее осведомлен в механизмах преобразования.
Заранее спасибо!

Автор: 500mhz 24.2.2011, 15:30
strace вам в помощ

Автор: borisbn 24.2.2011, 16:09
Цитата(Zerstroer @  24.2.2011,  14:58 Найти цитируемый пост)
s = (string)input;

так нельзя. ты пытаешься явно преобразовать указатель на char к классу string.
Нужно создать экземпляр класса string и передать ему в конструкторе указатель на char
Код

s = string( input );

и ещё. если ты не собираешься изменять данные по указателю input, сделай его const-овым
Код

string MyF(const char* input){
   string s = string( input ); // или так string s( input );
/*операции над s*/
  return s;
}


Автор: sergioK1 24.2.2011, 18:58
Цитата(borisbn @ 24.2.2011,  15:09)
Цитата(Zerstroer @  24.2.2011,  14:58 Найти цитируемый пост)
s = (string)input;

так нельзя. ты пытаешься явно преобразовать указатель на char к классу string.
Нужно создать экземпляр класса string и передать ему в конструкторе указатель на char
Код

s = string( input );

и ещё. если ты не собираешься изменять данные по указателю input, сделай его const-овым
Код

string MyF(const char* input){
   string s = string( input ); // или так string s( input );
/*операции над s*/
  return s;
}

если ты не собираешься изменять данные по указателю  ? что дает const ?
можно написать  ++input; или (input+5)=10;

Код

 string MyF(const char* input){
   string s = string( input ); // или так string s( input );
/*операции над s*/
  return s;
}



Автор: borisbn 24.2.2011, 19:07
Цитата(sergioK1 @  24.2.2011,  18:58 Найти цитируемый пост)
что дает const ?

то, что при вызове этой функции (MyF) ей можно передать констовый указатель, и быть уверенным, что данные по этому указателю не будут изменены
Код

string s1 = "Hello, sergioK1";
string s2 = MyF( s1.c_str() ); // После этой строки, если в функции параметр-указатель констовый,
                                              // можно быть уверенным, что в s1 осталось "Hello, sergioK1"
                                              // если же он не констовый, то это вообще не скомпилируется



Цитата(sergioK1 @  24.2.2011,  18:58 Найти цитируемый пост)
можно написать  ++input; или (input+5)=10;

если имеется в виду, что input - констовый указатель, то
++input можно, т.к. данные по указателю не изменяются, а
(input+5)=10 вообще нельзя, т.к. input+5 - rvalue. если же ты имел в виду *(input+5)=10, то так тоже нельзя,
т.к. если input - констовый указатель, то и (input+5) - тоже констовый указатель.

Автор: Zerstroer 24.2.2011, 20:13
Позвольте вопрос, а почему у меня как минимум 2 раза подобный финт ушами 
Код

 s = (string)input;

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

Автор: borisbn 24.2.2011, 22:30
Zerstroer, походу ступил малёха...
в данном случае
Код

s = (string)input;

и
Код

s = string( input );

одно и то же (хотя, вообще-то, предпочтительнее использовать второй вариант)

может быть у тебя в случае, когда программа падает, input указывает на мусор ? или равен NULL ?
распечатай input:
Код

string MyF(char* input){
   printf( "%p\n", input );
   printf( "%s\n", input );
return "";
/* string s = string( input );
  return s;
*/
}

Автор: Zerstroer 25.2.2011, 12:24
Того, что ступил - не исключаю!
Входную переменную char* input отслеживал.
Но.
1. При использовании 
Код

string s = string(input)

всё работает!
2. А при использовании 
Код

string s = (string)input

всё вываливается после 2-3 прогона.
Единственная предположительная догадка - input оканчивается не char(0) символом, а чем-то неведомым (насколько корректно формируется input сказать не могу - input подается из закрытого класса).

Автор: borisbn 25.2.2011, 12:29
Цитата(borisbn @  24.2.2011,  22:30 Найти цитируемый пост)
Zerstroer, походу ступил малёха...

это я про себя говорил smile
если 
Цитата(Zerstroer @  25.2.2011,  12:24 Найти цитируемый пост)
При использовании Без подсветки1:string s = string(input)highlightSyntax('nocolor_RhMTMz','nocolor');всё работает!

то предположение, что
Цитата(Zerstroer @  25.2.2011,  12:24 Найти цитируемый пост)
input оканчивается не char(0) символом, а чем-то неведомым

выглядит неправдоподобным.

всё-таки так
Код

string s = (string)input

неправильно. не должно работать. а то, что работает пару раз - так это, скорее всего, случайность

Автор: volatile 26.2.2011, 00:51
Не понимаю, зачем вообще использовать явное приведение?
Код

string s = input;  
И всё. smile 

Но похоже ошибка не здесь.
Цитата(Zerstroer @  25.2.2011,  12:24 Найти цитируемый пост)
input оканчивается не char(0) символом

это очень похоже, версия: Идет какойто очень длинный набор данных, malloc не может выделить так много и выпадает.
А иногда работает, потому-что в этом потоке данных случайно встретился '\0'.
Наличие или отсутствие '\0' может возникать от самых разных причин, так как строка перекрывает другие переменные, может стек, да вообще что угодно.

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


Автор: Zerstroer 27.2.2011, 19:38
volatile, 
Так, как вы сказали
Цитата(volatile @  25.2.2011,  22:51 Найти цитируемый пост)
код C++1:string s = input;  highlightSyntax('cpp_YTNiY2','cpp');И всё.  

точно нельзя! У меня input - указатель!

В принципе, первоначальную задачу я решил. Причины, по сути - не конкретны, проще запомнить верный метод.

borisbn, спосибо большое! Пошел учить специфику конструкторов/деструкторов стандартных классов.
Задача выполнена. Всем спасибо!

Добавлено через 3 минуты и 50 секунд
Задача решена. Правильный ответ 
string s = string( input );

Автор: volatile 27.2.2011, 20:05
Цитата(Zerstroer @  27.2.2011,  19:38 Найти цитируемый пост)
string s = input;  highlightSyntax('cpp_YTNiY2','cpp');И всё.  
точно нельзя! У меня input - указатель!


класс std::string имеет конструктор принимающий указатель на чар.
У вас видимо, что-то другое, не std::string


Автор: Zerstroer 27.2.2011, 20:11
Цитата(volatile @  27.2.2011,  18:05 Найти цитируемый пост)
класс std::string имеет конструктор принимающий указатель на чар.У вас видимо, что-то другое, не std::string

 у меня именно std::string. 
На синтаксис 
Код

string s = input

у меня ругается компиллятор, input - не const char*, а просто char*.
В конечном итоге, передача в конструктор идет способом, в первом же посте описанном borisbn
Код

string s = string( input );

Автор: volatile 27.2.2011, 20:19
Цитата(Zerstroer @  27.2.2011,  20:11 Найти цитируемый пост)
у меня ругается компиллятор, input - не const char*, а просто char*.

если не собираетесь менять input, объявите функцию как:
string MyF(const char* input)

если собираетесь

string s =  (const char*)input;

Добавлено через 10 минут и 39 секунд
это вообще кривость компилятора.

Автор: Zerstroer 27.2.2011, 20:33
input - изменяемый.

Код

string s =  (const char*)input;
 - такое я в первый раз вижу, но при возможности проверю и приму на вооружение! 

Автор: volatile 27.2.2011, 20:44
Если не работает 
string s = input;

то не должен работать и 
= string( input );

в обоих случаях вызывается конструктор string( const char* )


это явно кривой компилер. У вас под линухом видимо это нармально, господа линуксоиды ??? smile 


Автор: Zerstroer 27.2.2011, 20:56
*ловит камень летящий в огород*
Да самый лучший компилер! 
gpp/g++!
Это у вас неподлинуксом нормально когда
Цитата(volatile @  27.2.2011,  18:44 Найти цитируемый пост)
Если не работает string s = input;то не должен работать и = string( input );
!!!
А линукс система до крайностей адекватная!
Вот придёт borisbn и всё разъяснит!
Ладно, считаю дальнейшую палемику нежелательным флудом. smile 

Автор: borisbn 27.2.2011, 20:57
Цитата(Zerstroer @  27.2.2011,  19:38 Найти цитируемый пост)

Так, как вы сказали
string s = input; И всё.

точно нельзя! У меня input - указатель!


Цитата(Zerstroer @  27.2.2011,  19:38 Найти цитируемый пост)
Правильный ответ string s = string( input );

во всех компиляторах, которые я знаю, это - одно и то же !!!

Zerstroer, у тебя, скорее всего, какой-то ну очень древний компилятор...
тем более, что 
Цитата(Zerstroer @  27.2.2011,  20:11 Найти цитируемый пост)
у меня ругается компиллятор, input - не const char*, а просто char*.

по стандарту как раз обратное преобразование невозможно. а вот char * -> const char * - это не просто нормально, а супернормально.

Автор: volatile 27.2.2011, 21:17
string s = string( input );

здесь что происходит. сначала создается временный объект string, назовём его t
t = string( input );
потом создается объект s.
s (t);

а в строчке
string s = input;
никаких временных объектов не создается. и дело проходит за 1 шаг вместо 2-ух.


привет линуксоидам!!!

Автор: borisbn 27.2.2011, 21:25
Цитата(volatile @  27.2.2011,  21:17 Найти цитируемый пост)
никаких временных объектов не создается. и дело проходит за 1 шаг вместо 2-ух

линухоидов тоже не люблю, но, думаю, что cl.exe, что gcc разберуться и тупо один раз вызовут конструктор для вновь создаваемого объекта. впрочем ничего не мешает проверить: включить компиляцию через ассемблер - и вперёд smile

Автор: volatile 27.2.2011, 21:30
borisbn, да дело не в оптимизаторе.
почему в принципе нужно писать лишний код, и надеяться что оптимизатор это исправит?

Автор: borisbn 27.2.2011, 21:33
Цитата(volatile @  27.2.2011,  21:30 Найти цитируемый пост)
почему в принципе нужно писать лишний код

лишний - не нужно, а писать понятнее для самого себя - обязательно! даже если знаешь, что оптимизатор не исправит

Автор: volatile 27.2.2011, 21:45
borisbn, ну здесь не могу не согласиться.

Zerstroer, а вам все-же посоветую сменить компилер.
к линуксоидам, кстати, я нормально отношусь. 
smile 

Автор: bsa 27.2.2011, 22:04
Цитата(volatile @  27.2.2011,  20:44 Найти цитируемый пост)
 У вас под линухом видимо это нармально, господа линуксоиды ??

нет, это ненормально. У меня проблем с конвертацией char* в const char * никогда не было.

Цитата(volatile @  27.2.2011,  21:17 Найти цитируемый пост)
string s = string( input );

здесь что происходит. сначала создается временный объект string, назовём его t
t = string( input );
потом создается объект s.
s (t);

а в строчке
string s = input;
никаких временных объектов не создается. и дело проходит за 1 шаг вместо 2-ух.

Итак, есть два вида конструкторов.implicit и explicit. Все конструкторы по умолчанию implicit. Это значит, что код:
Код
string s = "sss";
//и
string s("sss");
Полностью идентичен - будет вызван один раз конструктор класса string.
Если бы конструктор string::string(const char *) был бы объявлен так: explicit string(const char *); то первый вариант просто бы не скомпилировался.
А вот код:
Код
string s = string("sss");
уже отличается от вышеприведенных. Так как в этом случае будет: вызов конструктора string::string(const char*), затем string::string(const string&) - конструктора копирования, и наконец деструктора string::~string().

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)