> Дело было не в сишных строках, а в особенностях Qt-ного QByteArray.data().Нет, вы не разобрались. Qt там вообще ни при чём. Вы просто не знаете C++.
> Этот вызов не гарантирует, что сразу после
> вызова полученный указатель будет указывать на корректные данные. Хотя в документации
> написано противоположное.
Конечно же гарантирует и указатель БУДЕТ указывать на корректные данные. Этот вызов просто выдаст вам адрес, по которому УЖЕ находятся данные. И опять же, Qt тут ни при чем.
Ваша проблема -- в незнании языка, документация Qt тут не поможет, нужно читать документацию на язык.
Чтобы не быть голословным, объясню, в чем на самом деле ваша проблема.
Это ваш код:
const char *message=msg.toLocal8Bit().data();
unsigned int messageLen=msg.toLocal8Bit().size();
printf("Len of line: %d\n", messageLen);
fwrite(message, sizeof(char), messageLen, stderr);
1. Когда вы делаете msg.toLocal8Bit() в правой части выражения (после равно), создается временный объект типа QByteArray.
2. После того, как первая строка вашего кода выполнится, этот временный объект автоматически удалится.
3. Поскольку ваша переменная message указывает на данные удалённого временного объекта QByteArray -- этот адрес, который она содержит -- невалидный (т.е. указывает на участок памяти, где может быть уже что угодно).
4. При попытке сделать fwrite(message), функция fwrite() пытается разыменовать message, но этот участок памяти уже не принадлежит вашему приложению, он был возвращен операционной системе при удалении временного объекта. Вот тут вы и получаете сегфолт, потому что попробовали залезть в память, которую ОС не выдавала вашему приложению.
Чтобы избежать этой проблемы, можно написать этот код так
{
// Use copy constructor to store temporary variable
QByteArray tmp(msg.toLocal8Bit());
const char *message = tmp.data();
unsigned int messageLen = tmp.size(); printf("Len of line: %d\n", messageLen);
fwrite(message, sizeof(char), messageLen, stderr);
}
Фигурными скобки ограничивают зону видимости временной переменной tmp. После закрывающейся фигурной скобки tmp будет уничтожена (т.к. она находится на стеке).
C++ замечательный язык и аналогов ему нет и не будет: он позволяет вам применять самые высокоуровневые абстракции (ООП, шаблоны и т.д.), генерируя при этом наиболее эффективный машинный код. Попытка сделать его проще для безоговорочно человека приведет к огромному увеличению потребления системных ресурсов вашим приложением. Но чтобы писать на нем, надо понимать, как он работает.
На самом деле я так понимаю вы никогда ничего на C++ не писали до этого? Надо понимать как работает язык. Почитайте Скотта Майерса "Эффективное использование C++. 55 верных советов". А лучше до этого почитайте Брюса Эккеля "Философия C++ (2 тома)".