Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Одномерный массив строк произвольной длины


Автор: ТРЕТЬ 26.6.2006, 09:17
Вот задача (не полный вариант, а именно, то на чем я погорел). Нужно создать одномерный массив строк произвольно длины, не более чем на 100 эл-тов (имеется ввиду что сами строки не ограничены по длине). Вот что далал я...
Код

char *string_array[101];

На сколько я понял, я этим задаю конструкцию "массив указателей на строки". Далее дописал нужные функции... Все реализованно через классы, ну да не важно... Запустил - ошибка (при чем не на уровне компиляции а во время выполнения)... При чем как-будто выход за предел массива. Проверил, не вылетает где-нибудь в программе счетчик за предела от 1 до 101. Вроде бы нет... Решил тогда вот такой тест провести.
Написал вот такую прожку.
Код

void main (void)
{
  char *string[101];
  string[0] = "hi";
  string[1] = "people";
  string[2] = "of the world";
  cout<<string[0]<<string[1]<<string[2];
  getch();
}

Сработало нормально... Решил все-такие еще проверить. Изменил код вот так.
Код

  string[0] = "hi";
  string[2] = "people";
  string[5] = "of the world";
  cout<<string[0]<<string[2]<<string[5];

Запускаю. И сразу ошибка! Такая же как в начале...
Тогда решил, что это мне Борланд свинью подкладывает (ВСРР 5.02). Смотрю, есть VC. Закинул туда код. С cout - ом почему-то не захотел работать, пришлось заменить на puts. И вот я с отвисающей челестью, смотрю, что программа работает, при чем обсолютно нормально!

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

Вот объясните мне пожалуйста, что я не так делал. Или это действительно ошибка компилятора? Может вы бы как-то по-другому решали бы эту задачу? Как? 

Автор: MAKCim 26.6.2006, 09:35
Цитата

Вот объясните мне пожалуйста, что я не так делал

если насчет примеров, все они рабочие (g++ 4.1) 

Автор: SaDFromSpb 26.6.2006, 14:08
Ты б написал, какая ошибка выскакивала. 

Автор: maalan 26.6.2006, 16:22
воотще говоря, это массив указателей!
и следовательно память для хранения строк никакая не выделялась
хранятся только указатель на строки.
для правильной работы надо выделить память под строки с помощью NEW
но так как надо иметь строки произвольной длины, то я бы сделал так
std::vector<vector<string> >string_array(100);

ну и далее по тексту
  string[0] = "hi";
  string[1] = "people";
  string[2] = "of the world";
  cout<<string[0]<<string[1]<<string[2];
  getch(); 

Автор: ТРЕТЬ 26.6.2006, 16:28
SaDFromSpb
Я бы и нарписал... Да только я же не помню на память, а то что оно мне писало то в универе и соталось=).

На самом деле сейчас настолько гадостное ощущение на душе... Просто дома пишу скрипт (в той же ВСРР 5.02) работает... А там нет... Блин, и из-за этого мне в среду опять идти на экзамен... Оператива у них там паленая что ли? Ну не может же такого быть, чтобы написать одно и то же и в одном месте оно работает без проблемм, а в другом никак... Обидно...

Добавлено @ 16:35 
maalan
Спасибо... Вот сейчас проверил, вроде выполняется... И почему мне это тогда в голову не пришло? жаль=)

Да и все равно опять же, если и без этого дома работает, то это скорее на глюк тянет. чем на то что реальная ошибка=) 

Автор: MAKCim 26.6.2006, 16:56
Цитата

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

все тут выделилось (в сегменте константных данных) и адрес этих строк присвоился указателям на стеке 

Автор: maalan 27.6.2006, 08:17
т.е. если написать
char * a;
a = "test";
то это нормально?

и если так написать
int *x;
*x = 100;
это тоже правильно? 

Автор: kirjanov 27.6.2006, 08:30
maalan
во 2 случае у тебя не инициализирован x, и 100 запишется, куда повезет. 

Автор: Fazil6 27.6.2006, 08:46
Цитата

т.е. если написать
char * a;
a = "test";
то это нормально?

ничего противозаконного
Цитата

и если так написать
int *x;
*x = 100;
это тоже правильно? 

это уже другой случай 

Автор: MAKCim 27.6.2006, 09:43
Цитата

во 2 случае у тебя не инициализирован x, и 100 запишется, куда повезет.  

в большинстве случаев вообще не запишется
а вылетит SEGMENTATION FAULT
Цитата

т.е. если написать
char * a;
a = "test";
то это нормально?

Цитата

Да, тип строкового литерала есть массив с надлежащим количеством символов
т. е "abc" принадлежит типу const char[4]. Строковый литерал можно присвоить переменной типа char*. Это разрешается поскольку в С типом строкового литерала был char*. Однако изменение строкового литерала через такой указатель является ошибкой.

Страуструп
 

Автор: maalan 27.6.2006, 09:50
 smile 
то-то я так эти charы не перевариваю smile
сказывается небольшой опыт в чистом си
с++ мне все-таки больше нДравиться
да и stl тоже красота 

Автор: MAKCim 27.6.2006, 10:10
Цитата

с++ мне все-таки больше нДравиться
да и stl тоже красота  

В том то и смысл ООП: инкапсулировать реализацию и предоставить приятный интерфейс
а на нижнем уровне STL (реализация) также и с указателями и с памятью работает 

Автор: maalan 27.6.2006, 11:07
Цитата

В том то и смысл ООП: инкапсулировать реализацию и предоставить приятный интерфейс
а на нижнем уровне STL (реализация) также и с указателями и с памятью работает 


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

Автор: MAKCim 27.6.2006, 11:52
Цитата

но до чего же все-таки не логично

все логично (см. цитату) 

Автор: maalan 27.6.2006, 12:41
Цитата(MAKCim @ 27.6.2006,  11:52)
все логично (см. цитату)

так в цитатах-то все логично, спору нетsmile
в поведении указателей нет логики
char не такой, как все остальные

и вообще, куда-то мы не туда в разговоре полезлиsmile на флейм похоже 

Автор: ТРЕТЬ 27.6.2006, 18:53
разрешите подвести итог...

По сути получилось, что я задал массив указателей на строки, которым выделилось нормальное количество места (кстати, тут еще вот такой вопрос: если скажем адресс одно строки допустим 0000х00 (не уверен, что такой адресс может существовать, но это условность) а следущая скажем в адресс 0000х01, то не получится ли так что первая строка "заползет" на вто рую при большой её длине?), а ошибка появилась из-за того, что, скажем, на той машине была подпорчена оператива, или например кампилятор заглючил жестоким образом? 

Автор: Romikgy 27.6.2006, 21:26
Цитата(maalan @  27.6.2006,  07:17 Найти цитируемый пост)
a = "test";

В таком варианте, строка представляется компилятору, как константная строка, и адресс на нее прописывает компилятор исходя из длинны строки, а уже потом этот адресс заносится в массив, и налазить никогда не будет, если конечно сам не налажаешь smile 

Автор: Mad 27.6.2006, 22:04
Цитата(ТРЕТЬ @  27.6.2006,  17:53 Найти цитируемый пост)
По сути получилось, что я задал массив указателей на строки, которым выделилось нормальное количество места (кстати, тут еще вот такой вопрос: если скажем адресс одно строки допустим 0000х00 (не уверен, что такой адресс может существовать, но это условность) а следущая скажем в адресс 0000х01, то не получится ли так что первая строка "заползет" на вто рую при большой её длине?), а ошибка появилась из-за того, что, скажем, на той машине была подпорчена оператива, или например кампилятор заглючил жестоким образом? 

скорей всего нет, и ошибку допустил именно ты smile

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

внимательно проверь код.
(а лучше выложи его тут, посмотрим и найдем) 

Автор: Fazil6 27.6.2006, 22:25
Цитата

В таком варианте, строка представляется компилятору, как константная строка, и адресс на нее прописывает компилятор исходя из длинны строки

при чем здесь длина? 

Автор: MAKCim 28.6.2006, 08:54
Цитата

при чем здесь длина?  

чем длиннее строка, тем больше надо памяти под нее, а значит ищется непрерывная область памяти большего размера
т. е длина является одним из критериев выбора место хранения 

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