LINUX.ORG.RU

C, C++. Какова максимальная длина сишных строк (сегфолт на строке длиной ~640 Кб, GCC)?


0

4

Сейчас словил сегфолт при выводе строки длиной 636180 байт.

Сегфолтная команда:

fprintf(stderr, "%s", message);

где message имеет тип «const char *message» и размер данных в 636180 байт.

В стеке вызовов видно, что после функции fprintf() были вызваны:

strlen ()	
__GI__IO_fputs (str=0xb2379018 <Address 0xb2379018 out of bounds>, fp=0xb6ecc960 <_IO_2_1_stderr_>)

- т. е. сначала fputs(), последней strlen().

Сегфолт в дебрях strlen(). (Мне не нравится и строка с fputs(), ибо в ней «Address 0xb2379018 out of bounds»).

Таких проблем на коротких строках (чуть более 1000 знаков) не возникает.

Вопрос: существуют какие-то ограничения в компиляторах на работу с сишными строками? Я то думал, что размер строки ограничивается максимальным числом unsigned int. А тут вона как - 630 КБ прожевать не может.

Или, к примеру, существует какое-то ограничение на работу с потоком ошибок, только я о нем не знаю?

Если это важно: gcc (Debian 4.7.1-7) 4.7.1

★★★★★

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

toLocal8Bit возвращает объект QByteArray, для которого вызывается метод data. Дальше компилятор считает, что этот временный объект никому не нужен и разрушает его. Результирующий указатель продолжает указывать на данные уже разрушенного объекта.

Ты действительно так считаешь или троллишь?

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

Фак мой мосг.

Расположил пресловутый QByteArray на стеке и он живёт пока не стек не отмотнётся назад. Маленькая очепятка, если знать что такое стек и как он работает, всё должно быть понятно.

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

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

fixed

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

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

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

Всё так. Я пытаюсь тебе помочь чему-то научиться (раз уж ты влез в в этот тред и блестаешь не знанием элементарных вещей), а ты по факту ссылок на учебные материалы жирно вбрасываешь. Давай удачи тебе, иди поищи еду вкуснее.

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

Пока тролишь ты. Сам собери небольшой пример и выложи кусок кода сюда, и мы вместе посмотрим что там происходит. Ok?

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

Ещё один. Буду вежлив.

Иди уже почитай нормальные книги по C++.

Как это изменит факт, благодаря которому, моё решение (+бегемот) работает?

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

Сам собери небольшой пример и выложи кусок кода сюда

См. рис. 1

ziemin ★★
()

Тред - просто канонический пример типичных крестопроблем. Деструкторы у них вызываются после выхода из экспрешшна, вот это цирковые трюки.

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

Если выражение передавать в функцию, то компилятор не разрушит ее до выхода из этой функции. Т.е. временный безимянный объект QByteArray будет жить до выхода из функции и указатель возвращаемый data будет указывать на валидные данные.

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

Деструкторы у них вызываются после выхода из экспрешшна, вот это цирковые трюки.

Ещё один? Да не вызывается ничего, если далее есть использование. А если и вызаются, то это побочный эффект библиотеки.

Если что в треде сплошные толли.

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

Да не вызывается ничего, если далее есть использование. А если и вызаются, то это побочный эффект библиотеки.

Ты совсем какой-то тугой. При чем здесь библиотека?

#include <iostream>
#include <cstring>

class Foo
{
public:
    Foo()
    {
        std::cout << "Foo()" << std::endl;
        data = new char[128];
        strcpy(data, "ziemin don't know 'bout my destructors");
    }

    ~Foo()
    {
        std::cout << "~Foo()" << std::endl;
        delete[] data;
    }

    char * GetData() { return data; }

private:
    char *data;
};

int main()
{
    char *data = Foo().GetData();
    std::cout << data << std::endl;
    std::cout << "Exiting..." << std::endl;
    return 0;
}

Выводит:

Foo()
~Foo()
<какой-то треш>
Exiting...

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

Эм. Я плохо C/C++ знаю. А где здесь выделение памяти под объект Foo? Ключевое слово new не наблюдаю. Методы не статические.

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

А как проблема в strcpy, выхватыватель вы наш с наметанным глазом? Поделитесь? Ты правда не находишь связи с темой? Ты вообще о чем здесь дискутируешь? :))))

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

Вот здесь создается безимянный автоматический объект: Foo(), для которого и вызывается метод GetData.

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

Я это говорил с самого начала. Но ты же в очередной раз показал, что ты писатель, а не читатель. :)))

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

забавно если после окончания треда ziemin умрёт от баттхерта инфаркта. Или erfea, кто-нибудь из них. А вот если бы не было С++, не было бы таких смешных тредов и пришлось смотреть бы унылый телевизор по вечерам.

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

где выступал? Два человека утверждают одно и то же, отчаянно споря друг с другом. ГБшник допрашивает поциента но он отмалчивается, не говорит паролей, явок и места в QString где написано проблемное место. Отшелник с огнём в глазах проповедует Основы. Крестачер рисует в гимпе картинку про выкрутасы, но капча не набирается который раз. Маша трахнула Дашу, потом Петю и Бобика. Пью чай на раёне, жму F5 и жду развития событий.

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

Наиболее интересны следующие темы: интеллект С++ сам убивает посередине экспрешшена, что угодно превращается в char* с помощью особой, stl магии, и есть ли жизнь на марсе. Всё это очень важно.

stevejobs ★★★★☆
()
Последнее исправление: stevejobs (всего исправлений: 1)
Ответ на: комментарий от stevejobs

забавно если после окончания треда ziemin умрёт от баттхерта инфаркта. Или erfea, кто-нибудь из них. А вот если бы не было С++, не было бы таких смешных тредов и пришлось смотреть бы унылый телевизор по вечерам.

Чего это со мной что-то случится? :D У меня всё хорошо, я умею писать код, понимаю что и как делаю. Свободно справляюсь с задачами на разных ЯП от крестов и жабы до таких изысков как lsl. Знаю сильный и слабые стороны многих ЯП, делюсь опытом и знаниями с людьми когда есть время и настроение. Если у кого-то мои указания на слабые познания в программировании и отсылки к учебным материалам вызывают батхерт, сие не есть моя проблема. Я таки никого не тролил, да спокойно самоудалился, из треда ибо доказывать невежам что-то не есть интересное занятие. Не кастовали бы, дык не вернулся б. Мир, дружба, жвачка. ;)

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

Этот тред мне более не интересен. Если хочешь поддерживай. Это не трудно. Просто ответь школьника цитатами и всё.

ГЗВ: даже выдумывать ничего не надо - они и реальные цитаты воспримут неожиданно

ziemin ★★
()
Последнее исправление: ziemin (всего исправлений: 1)
Ответ на: комментарий от ziemin

Конечно тебе он не интересен. Как может быть интересен тред в котором ты нихрена не понимаешь. :))))

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

Мне вот тоже со стороны жабы такие вещи кажутся трешем полным. Крестовикам, которые говорят, что жаба/дотнеты тормозят, приходится платить за счв своеобразную плату. (:

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

Это счет чего? :)))) Сам играешь - сам побеждаешь? Ну что молодец. К сожалению больше о С++ ты знать не стал. Ну это и не важно, твои заблуждения останутся с тобой.

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

Мне вот тоже со стороны жабы такие вещи кажутся трешем полным. Крестовикам, которые говорят, что жаба/дотнеты тормозят, приходится платить за счв своеобразную плату. (:

Мне как человеку пользующему оба ЯП, видятся определённые жертвы в выборе любого из двух ЯП. И как правило я предпочитаю больше поработать головой применяя кресты, чем расслабиться и получить заведомо менее качественный результат (жаба не даёт мне инструментов для контроля над работой программы в нужном объёме). Защита от выстрела в ногу дорого обходится, привычка сидеть на расслабоне приводит не только к всплытию объективных недостатков ЯП, но и к недееспособности программиста. Большинство жабофилов сами не умеют правильно применить свой ЯП, потому как не имеют никакого представления о том что же таки делает их код. Та же проблема и среди последователей крестов, но реже ибо сей ЯП вынуждает хотя бы что-то усвоить из вещей глубоко спрятанных от простого былокодера. Сей тред есть результат элементарной безграмотности, жабофилу его ЯП такое прощает, но собирает свою жатву, в крестах сегфолт в зубы и радуйся. Оба ЯП имеют свои недостатки и плюсы, нужно лишь применять их там где это уместно и делать это правильно. Программист должен прежде всего знать что делает он и его код, программирование - процесс принятия решений и поисков компромисса. Программист, если он профессионал, борется не с детскими проблемами типа сабжа треда, а принимает решения о том какой из кучи вариантов выполнения задачи лучше в данной ситуации. И тут важно учитывать и потребление памяти, и производительность, и время затрачиваемое на выполнение работ. А кидание какашками друг в друга из-за личной не приязни к инструменту - удел слабоумных макак. Выбирай инструмент не из любви к нему, а из его объективных характеристик и прочих условий выполнения задачи.

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

Дельно глаголете, сударь.

Благодарю за понимание. Последнее время тут окромя троллей, видящих (в каждом написанном кем либо слове) лишь возможность покривляться, мало народу. Заходить даже редко стал.

erfea ★★★★★
()
Последнее исправление: erfea (всего исправлений: 1)
Ответ на: комментарий от Begemoth

int - это минимум 4 байта

Так что int - минимум 2 байта

Ваш следующий ход, сер.

sergijoo
()

То ли у меня алкоголь уже глаза застилает, то ли я чего-то не понял, но вот эта фигня

#include <stdio.h>
#include <stdlib.h>
main(){
	int L = 1024*1024;
	char *msg = malloc(L), *ptr = msg; // ага, 1 мыгабайт
	for(int i = L-1; i > 0; i--)
		*ptr++ = 'a';
	*ptr = 0;
	printf("А вот и строчечка:\n%s\n", msg);
}
работает!

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

Почему ты его здесь ждешь? У ТС он происходил совсем по другой причине. Ну выше писали уже. :)

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

В том что ТС получал указатель на данные во временном объекте, который разрушался быстрее, чем этот указатель использовался. Как только время жизни этого объекта была продлена до времени работы печатающей функции - все заработало.

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

Твоё решение - двадцать раз пересоздать QByteArray из строки. Да, конечно, работает. Вот только конвертация происходит не один раз.

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