LINUX.ORG.RU

Третий день бьюсь над сегфолтом...

 , , , ,


1

4
#include <string.h>
#include <iostream>
using namespace std;
const int ARL=255;
class String{
 char* s[];
 public:
 String(char *s1){
  s=new char[ARL];
  strcpy(s,s1);
 }
 String(){
  cout<<"Введите строку:";
  s=new char[ARL];
  cin>>s;
 }
 ~String(){
  delete[] s;
 }
 int len(){
  for (int i=0;i<ARL;i++)
   if (s[i]==0)
    return i;
  return -1;
 }
 int len(char* s1){
  int l=sizeof(*s1);
  for (int i=0;i<l;i++)
   if (s1[i]==0)
    return i;
  return -1;
 }
 void operator--(){
  int l=this->len();
  int j;
  for(int i=0;i<l;i++){
   ........
  }
 }
..............
};
int main(){
 char* s=new char[255];
 cout<<"Введите начальную строку:"<<endl;
 cin>>s;
 String* s1=new String(s);
 s1->print();
 *s1--;
 s1->print();
...................
 return 0;
}

Первый раз метод len вызывается корректно. При втором - сразу сегфолт. С помощью gdb выяснил, что s почему-то присваивается между этими вызовами адрес 0x21. Где и как - хоть убейте, не пойму. Если s1-- закомментить - не сегфолтится. Пробовал его и со звёздочкой вызывать, и без - результат один и тот же.

Ничего не понял. Код лапша.

false ★★★★★
()

Посмотри sizeof(t) ради интереса, и разберись в чём разница между массивами и указателями, как объявляются те и другие, после чего попробуй объяснить что объявил ты. А так, конечно, это не единственная проблема, весь код - чистый бред. Начни с чего-нибудь одного - либо разбирайся с прямой работой с памятью и не лезь в C++, либо разбирайся с C++ и не прикасайся к прямой работе с памятью.

slovazap ★★★★★
()

char* s[];

WTF?

зачем тут []???

cin>>s;

facepalm

это вам не бейсик...

PS: кривой косой велосипед вместо strlen(3) это только начало? Остальное искать на говнокод.ру?

emulek
()
Ответ на: комментарий от MiniRoboDancer

Даже если оставить только класс String, он уже не компилируется:

testttt.cpp: In constructor ‘String::String(char*)’:
testttt.cpp:9:4: error: incompatible types in assignment of ‘char*’ to ‘char* [0]’
   s=new char[ARL];
hope13 ★★★
()
Ответ на: комментарий от slovazap

Тут, блин, задача долбонутая. Работать надо на голом C++, используя классы, переопределение операторов, а работа со строками должна быть прямой, без использования std::string и прочего. Вот и выкручивайся...

MiniRoboDancer ★☆
() автор топика
Ответ на: комментарий от nanoolinux

Это же новое определение единицы!!!!1111

AIv ★★★★★
()
Ответ на: комментарий от nanoolinux

Мне по барабану, это копипаст более ранней версии метода без параметров, до которого ещё руки не дошли, всё равно нигде не используется.

MiniRoboDancer ★☆
() автор топика

int l=sizeof(*s1);

И что по вашему вы получите в качестве результата в l?

strcpy(s,s1);

А если s1 >= ARL?

int l=this->len();

Тут this избыточен.

andreyu ★★★★★
()

char* s[];

О, это я и не заметил сразу. Вы с памятью вообще работать не умеете. Используйте контейнеры, и потихонечку читайте K&R.

andreyu ★★★★★
()
Ответ на: комментарий от emulek

зачем тут []???

Сорри, дописал в порыве безысходности и так и скопировал. Ещё даже не сохранял и тем более не компилил.

кривой косой велосипед вместо strlen(3) это только начало?

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

MiniRoboDancer ★☆
() автор топика
Ответ на: комментарий от nanoolinux

Внезапно, тут проблем нет. Я проверял, в s строка корректно по байтам хранится. До второго вызова. Собственно, до него что-то неявно происходит. НО ЧТО??? Откуда берётся 0x21?

MiniRoboDancer ★☆
() автор топика
Ответ на: комментарий от hope13

У меня компилится. g++. А оно должно быть как-то иначе?

MiniRoboDancer ★☆
() автор топика
Ответ на: комментарий от MiniRoboDancer

Сорри, дописал в порыве безысходности и так и скопировал. Ещё даже не сохранял и тем более не компилил.

ага... А вот как на ЛОР насрать — это ты первый...

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

Hint: используй круглые колёса.

И да, если ты «всё на голом с++» пишешь, то какого хрена у тебя std::operator>>()??? Это STL, детка. Тут без ассемблера никак (раз уж ты даже strlen(3) не можешь юзать).

emulek
()
Ответ на: комментарий от MiniRoboDancer

Собственно, до него что-то неявно происходит. НО ЧТО??? Откуда берётся 0x21?

ты и так всю тему говном измазал... Хрен знает...

Низзя. Курс ООП.

Ок, почему STL нельзя? Какого хрена вообще в ООП делают эти низкоуровневые указатели?

emulek
()
Ответ на: комментарий от emulek

Я б юзал printf/scanf, но под плюсами не пашут. И вообще, не я ж такие упоротые задачи придумываю:D Там ещё один из методов должен строку чистить от псевдографики. Какая, нахрен, псевдографика в 2013-м году? В Win1251 её нет, уж не знаю, как там виндузятники выкручиваются, cp866 без костылей работает только под XP, XP пользуется от силы пару человек, а остальные костыли вряд ли осилят. А мне пришлось консоль в КОИ переключать, дабы не трахаться с wchar. Но и без wchar изврат полнейший.

MiniRoboDancer ★☆
() автор топика
Ответ на: комментарий от MiniRoboDancer

у Вас len() для любой непустой строки возвращает -1. Но вообще то почитайте что ли книжек... и запуститесь уже под valgrind.

AIv ★★★★★
()

Мои глаза... На кой выделять строку на куче если в твоем случае достаточно на стеке? На кой ты вообще работаешь с голыми указателями. Особенно с передачей жестко заданного массива, судя по коду ты понимаешь что такое перегрузка операторов. Тогда на кой ты не перегружаешь оператор '>>'?
Вот лучше почитай вот это: http://www.cplusplus.com/reference/istream/istream/operator>>/

V1KT0P ★★
()
Ответ на: комментарий от MiniRoboDancer

Я б юзал printf/scanf, но под плюсами не пашут.

ЩИТО?

И вообще, не я ж такие упоротые задачи придумываю:D

ты этта: 1. пусть делится веществами с тобой. 2. И со мной — тоже. Ня.

Там ещё один из методов должен строку чистить от псевдографики. Какая, нахрен, псевдографика в 2013-м году?

ВНЕЗАПНО

  	  	0 	1 	2 	3 	4 	5 	6 	7 	8 	9 	A 	B 	C 	D 	E 	F
2500 	  	─ 	━ 	│ 	┃ 	┄ 	┅ 	┆ 	┇ 	┈ 	┉ 	┊ 	┋ 	┌ 	┍ 	┎ 	┏
2510 	  	┐ 	┑ 	┒ 	┓ 	└ 	┕ 	┖ 	┗ 	┘ 	┙ 	┚ 	┛ 	├ 	┝ 	┞ 	┟
2520 	  	┠ 	┡ 	┢ 	┣ 	┤ 	┥ 	┦ 	┧ 	┨ 	┩ 	┪ 	┫ 	┬ 	┭ 	┮ 	┯
2530 	  	┰ 	┱ 	┲ 	┳ 	┴ 	┵ 	┶ 	┷ 	┸ 	┹ 	┺ 	┻ 	┼ 	┽ 	┾ 	┿
2540 	  	╀ 	╁ 	╂ 	╃ 	╄ 	╅ 	╆ 	╇ 	╈ 	╉ 	╊ 	╋ 	╌ 	╍ 	╎ 	╏
2550 	  	═ 	║ 	╒ 	╓ 	╔ 	╕ 	╖ 	╗ 	╘ 	╙ 	╚ 	╛ 	╜ 	╝ 	╞ 	╟
2560 	  	╠ 	╡ 	╢ 	╣ 	╤ 	╥ 	╦ 	╧ 	╨ 	╩ 	╪ 	╫ 	╬ 	╭ 	╮ 	╯
2570 	  	╰ 	╱ 	╲ 	╳ 	╴ 	╵ 	╶ 	╷ 	╸ 	╹ 	╺ 	╻ 	╼ 	╽ 	╾ 	╿
2580 	  	▀ 	▁ 	▂ 	▃ 	▄ 	▅ 	▆ 	▇ 	█ 	▉ 	▊ 	▋ 	▌ 	▍ 	▎ 	▏
2590 	  	▐ 	░ 	▒ 	▓ 	▔ 	▕ 	▖ 	▗ 	▘ 	▙ 	▚ 	▛ 	▜ 	▝ 	▞ 	▟

дабы не трахаться с wchar. Но и без wchar изврат полнейший.

ты этта, сначала осиль обычные буквы. Которые ASCII.

emulek
()
Ответ на: комментарий от emulek

Хрен знает...

А я тем более. Явно между теми местами s точно никто не трогает. Вон вальгринда как раз скачалась, ещё под ней отладить попробую.

Ок, почему STL нельзя?

Тут даже скорее из рациональных побуждений. У меня вот никакой уверенности нет, что стандартные методы работы со строками и мои действуют одинаково. Лучше уж сразу налепить своё, даже если оно отойдёт от стандартной реализации C-шных строк, но хоть конфликтов не будет. std::string вообще не катит, в предыдущах лабах препод на него не обращал внимание, но в этой строго указал - использовать нельзя, надо всё написать своё. Сам во всех примерах кода использует только char*.

MiniRoboDancer ★☆
() автор топика
Ответ на: комментарий от MiniRoboDancer

Я б юзал printf/scanf, но под плюсами не пашут.

Эх, да ты ещё и пьян к тому же.

nanoolinux ★★★★
()

Жесть. Тут сегфолт почти на каждой строке может быть :)

Reset ★★★★★
()
Ответ на: комментарий от AIv

для любой непустой строки возвращает -1

Корректно работает, я проверял.

Но вообще то почитайте что ли книжек...

Да читаю я какой-то дремучий учебник... там вообще рекомендуется вместо s использовать *(s+i) :D

MiniRoboDancer ★☆
() автор топика

Первый раз метод len вызывается корректно.

Открою тайну. Он не вызывается вообще.

anonymous
()
Ответ на: комментарий от emulek

ЩИТО?

А ты предлагаешь другие варианты?

ВНЕЗАПНО

Я в курсе, что оно есть в Юникоде. Но мне от этого не легче. Вообще постановка задачи тупая, кто будет псевдографику с клавиатуры вводить? Не под DOS же это пускается.

Которые ASCII.

В ASCII их вообще нет, если ты не относишь к ней расширенную таблицу, которая в каждой кодировке разная.

MiniRoboDancer ★☆
() автор топика
Ответ на: комментарий от MiniRoboDancer

У меня вот никакой уверенности нет, что стандартные методы работы со строками и мои действуют одинаково.

свои можешь запихать себе в ж. Они всё равно не работают.

но в этой строго указал - использовать нельзя, надо всё написать своё. Сам во всех примерах кода использует только char*.

тогда юзай printf/scanf. Препод будет доволен.

Hint: никогда не делай IO в конструкторах/деструкторах. И память не выделяй. НИКОГДА.

Hint2: делай деструкторы виртуальными. Никаких исключений. Иначе rule34.

Hint3: явно перезагружай конструктор копий и оператор=. ВСЕГДА, тем более, когда он тебе не нужен.

Hint4: надо больше const. Чем больше const, тем лучше код.

Hint5: опасайся синдрома class->void*->class.

Hint6: свои велосипеды сунь себе в жоппу. Им там самое место. Даже не показывай, я знаю, что это так.

Hint7: может C++ не так уж хорош, как думают некоторые? Подумай об этом. Всем известно, что Java быстрее, а писать код проще. А ещё он не сегфолтится.

emulek
()
Ответ на: комментарий от anonymous

Это, кстати, первое, что бросается в глаза: *s1--;

Типа чтобы вызвать оператор. А вот не сработает.

anonymous
()
Ответ на: комментарий от MiniRoboDancer

Я б юзал printf/scanf, но под плюсами не пашут.

Комманды эмулятора терминала vt100 не пашут в плюсах?%)

anonymous
()
Ответ на: комментарий от emulek

Они всё равно не работают.

4.2

тогда юзай printf/scanf

Расскажешь ещё может, как их вызывать под плюсами?

Хинты твои мне в данном случае ни к чему вообще. Ибо не соответствуют упоротым требованиям упоротого препода.

MiniRoboDancer ★☆
() автор топика
Ответ на: комментарий от anonymous

Мысль развивать? Вместо вызова оператора происходит декремент указателя, после чего s разумеется будет указывать вникуда.

anonymous
()
Ответ на: комментарий от AIv
==14132== Invalid read of size 8
==14132==    at 0x400D17: String::len() (oop_lab4.cpp:22)
==14132==    by 0x400D59: String::print() (oop_lab4.cpp:78)
==14132==    by 0x400C4F: main (oop_lab4.cpp:93)
==14132==  Address 0x59f6178 is 8 bytes before a block of size 8 alloc'd
==14132==    at 0x4C298F9: operator new(unsigned long) (vg_replace_malloc.c:298)
==14132==    by 0x400C1C: main (oop_lab4.cpp:90)

Полезной инфы ещё меньше. Как её использовать-то правильно?

MiniRoboDancer ★☆
() автор топика
Ответ на: комментарий от MiniRoboDancer

А ты предлагаешь другие варианты?

я даже и не знаю...

Я в курсе, что оно есть в Юникоде. Но мне от этого не легче. Вообще постановка задачи тупая, кто будет псевдографику с клавиатуры вводить? Не под DOS же это пускается.

ВНЕЗАПНО: use vim.

В ASCII их вообще нет, если ты не относишь к ней расширенную таблицу, которая в каждой кодировке разная.

я к тому, что осиль сначала строки в ASCII, а потом переходи на UTF-8.

emulek
()
Ответ на: комментарий от anonymous

Как это может декрементиться член класса, если декрементиться должен сам класс? Тогда оно декрементится всё сразу и s оказывается вообще хрен знает где... И как, в таком случае, эту всю галиматью корректно описать и вызвать?

MiniRoboDancer ★☆
() автор топика
Ответ на: комментарий от MiniRoboDancer

Расскажешь ещё может, как их вызывать под плюсами?

может ещё рассказать, на какие кнопки надо нажать, что-бы man 3 printf прочитать?

Хинты твои мне в данном случае ни к чему вообще. Ибо не соответствуют упоротым требованиям упоротого препода.

это ты так думаешь...

emulek
()
Ответ на: комментарий от AIv

Тот я вообще нигде не использую. Биборан будет переписан.

MiniRoboDancer ★☆
() автор топика
Ответ на: комментарий от MiniRoboDancer

если декрементиться должен сам класс?

делить на ноль нельзя.

И как, в таком случае, эту всю галиматью корректно описать и вызвать?

не трогать C++, пока не подрос.

emulek
()
Ответ на: комментарий от MiniRoboDancer

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

(*s1) --;
anonymous
()
Ответ на: комментарий от emulek

ВНЕЗАПНО: use vim.

Не слишком ли велик огород для того, чтобы текст в программу передать?

я к тому, что осиль сначала строки в ASCII, а потом переходи на UTF-8.

И C-шные строки, и методы работы с ними я уже давным-давно осилил. Вот только толку с этого сейчас 0.

MiniRoboDancer ★☆
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.