Russian Qt Forum

Qt => Общие вопросы => Тема начата: blackalegator от Май 25, 2013, 03:27



Название: Смена мест байтов в QByteArray
Отправлено: blackalegator от Май 25, 2013, 03:27
Тренируюсь в c++/Qt. (Перехожу с явы) Дается все нелегко, ссылки, указатели и тп заставляют периодически рвать волосы на своей голове. В качестве упражнения решил написать функцию для смены мест байтов в QByteArray. Вот к чему пришел:
Код:
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);

        QString t = "abcde";
        QByteArray test= t.toLatin1();

        qDebug() << test;
        qDebug() << QString(swapBytes(test,0,3));

        return a.exec();
    }

    QByteArray swapBytes(QByteArray in, int swapOffset, int quantity) {
        if (swapOffset < 0) {
            return in;
        }
        if(quantity>(in.length()/2)) {quantity=in.length()/2;}
        if(quantity < 1) {quantity=1;}
        int k;
        char buf[quantity];
        char buf2[quantity];
        memset(buf, 'z', quantity); memset(buf2, 'z', quantity);
        qDebug() << quantity;
        for (int i = 0; i + quantity*2 + swapOffset <= in.length(); i=i+2*quantity) {
            k=i;
            for(int b = 0;b<quantity;b++){
                buf[b]=in.at(k);
                buf2[b]=in.at(k+swapOffset+quantity);
                k++;
            }
            qDebug() << buf;
            qDebug() << sizeof(buf);
            qDebug() << (int)buf[1];
            qDebug() << buf2;
            qDebug() << in;
            in.replace(i,quantity,buf2);
            qDebug() << in;
            in.replace(i+quantity+swapOffset,quantity,buf);
        }
        return in;
    }
}

К сожалению по неизвестной причине у меня на выходе выводиться
abcde
ab(
cd
abcde
cdcde
cdab(e

Я не понимаю откуда вываливается эта скобка. Так же, если поменять входной массив на


Название: Re: Смена мест байтов в QByteArray
Отправлено: Igors от Май 25, 2013, 10:01
Непонятно что Вы хотите получить. Напр 20 элементов, swapOffset = 2, quantity = 4. Какой результат ожидается?


Название: Re: Смена мест байтов в QByteArray
Отправлено: Old от Май 25, 2013, 10:07
Тренируюсь в c++/Qt.
Нужно вначале натренироваться с C++, а потом подходить к Qt.

(Откуда там бесконечный цикл я не понимаю)
Нужно уже знать, что такое:
Код
C++ (Qt)
char buf[ len ];
и как к этому относиться qDebug(), тогда станет понятно почему он не останавливается при выводе.


Название: Re: Смена мест байтов в QByteArray
Отправлено: Странник от Май 25, 2013, 10:33
На stackoverflow предложили инициализировать buf и buf1. Не помогло
и правильно предложили, нуль-терминированные же строки. в приведенном коде инициализации нет.
кроме того, buf и buf2 у вас размера quantity (забыли зарезервировать символ под нуль-терминатор), при этом в цикле они заполняются и вовсе до i+quantity - выход за границы массива просто по всем фронтам.


Название: Re: Смена мест байтов в QByteArray
Отправлено: blackalegator от Май 25, 2013, 13:46
Я изменил код. (В главном посте новый) Писал глубокой ночью, поэтому и написал i+quantity. С длинными строками все работает, но пример с abcde не работает опять. Появляется скобочка. После этого решил вывести в qDebug() << buf[2] и вылезла та самая скобочка. Почитал описание replace и вот что нашел:

QByteArray & QByteArray::replace(int pos, int len, const char * after)
This is an overloaded function.

Replaces len bytes from index position pos with the zero terminated string after.

Notice: this can change the length of the byte array

Довольно странно. По идее она должна была заменить только 2 байта
(У меня было in.replace(i+quantity+swapOffset,quantity,buf);
Однако она меняла 3. Поменял ее на in.replace(i+quantity+swapOffset,quantity,buf,quantity);
И все полностью заработало.

Заодно узнал, что в с++ выход за границы массива не останавливает программу, как в Java. Спасибо всем мне помогавшим


Название: Re: Смена мест байтов в QByteArray
Отправлено: blackalegator от Май 25, 2013, 15:54
На stackoverflow предложили инициализировать buf и buf1. Не помогло
и правильно предложили, нуль-терминированные же строки. в приведенном коде инициализации нет.
кроме того, buf и buf2 у вас размера quantity (забыли зарезервировать символ под нуль-терминатор), при этом в цикле они заполняются и вовсе до i+quantity - выход за границы массива просто по всем фронтам.

Нуль-терминатор? Прямо страшно становиться. Что это такое?


Название: Re: Смена мест байтов в QByteArray
Отправлено: Igors от Май 25, 2013, 16:15
Чувствуется кладка "жабиста"  :) К слову
Код:
    QByteArray swapBytes(QByteArray in, ...
Хотя это приемлемо в Qt, с точки зрения языка - говнокод. Такое ускорять хорошо (раз так в 5-10)  :)


Название: Re: Смена мест байтов в QByteArray
Отправлено: Странник от Май 26, 2013, 10:15
Нуль-терминатор? Прямо страшно становиться. Что это такое?
Нуль-терминатор - символ '\0' (с кодом 0). он считается символом завершения строки. если при передаче строки в функцию вы не указываете ее длину явно, строкой считается все от начала до первого вхождения нуль-терминатора. если же ваша строка нуль-терминатора не содержит, происходит выход за границы.
Речь идет о С-строках, разумеется.


Название: Re: Смена мест байтов в QByteArray
Отправлено: Авварон от Май 26, 2013, 21:05
Хотя это приемлемо в Qt, с точки зрения языка - говнокод. Такое ускорять хорошо (раз так в 5-10)  :)

Што? Это является узким местом?


Название: Re: Смена мест байтов в QByteArray
Отправлено: Igors от Май 27, 2013, 11:29
Што? Это является узким местом?
Да, если имплисит шара не подотрет сопли, напр
Код:
std::vector swapBytes(std::vector in, ...


Название: Re: Смена мест байтов в QByteArray
Отправлено: Fregloin от Май 29, 2013, 17:38
еще лучше передавать ссылку, быстрее будет вызов процедуры происходить, почитайте про передачу/возврат параметров в функции с++...


Название: Re: Смена мест байтов в QByteArray
Отправлено: Авварон от Май 29, 2013, 23:06
Што? Это является узким местом?
Да, если имплисит шара не подотрет сопли, напр
Код:
std::vector swapBytes(std::vector in, ...

Вы же прекрасно понимаете, что ботлнеком оно станет только при 100500 вызовах, а у автора-это не так.


Название: Re: Смена мест байтов в QByteArray
Отправлено: Igors от Май 30, 2013, 08:56
Вы же прекрасно понимаете, что ботлнеком оно станет только при 100500 вызовах, а у автора-это не так.
А зачем разбираться "так или не так" - гораздо проще всегда подавать приличные структуры по ссылке или указателю


Название: Re: Смена мест байтов в QByteArray
Отправлено: Авварон от Май 30, 2013, 11:07
Вы же прекрасно понимаете, что ботлнеком оно станет только при 100500 вызовах, а у автора-это не так.
А зачем разбираться "так или не так" - гораздо проще всегда подавать приличные структуры по ссылке или указателю

Затем, что разбираться всё равно придётся - сказать навскидку, где ботлнек в программе, сложно. А, экономя на спичках, вы только себе жизнь усложняете (я про тот случай, когда оптимизация ухудшает читаемость\простоту использования кода).


Название: Re: Смена мест байтов в QByteArray
Отправлено: Igors от Май 30, 2013, 11:13
Затем, что разбираться всё равно придётся - сказать навскидку, где ботлнек в программе, сложно. А, экономя на спичках, вы только себе жизнь усложняете (я про тот случай, когда оптимизация ухудшает читаемость\простоту использования кода).
Код
C++ (Qt)
void MyFunc( const Container & c  ...)  // это не вызывает никаких вопросов
void MyFunc( Container c  ...)   // а что это ?? Так задумано, или описАлся ??


Название: Re: Смена мест байтов в QByteArray
Отправлено: Странник от Май 30, 2013, 11:14
Затем, что разбираться всё равно придётся - сказать навскидку, где ботлнек в программе, сложно. А, экономя на спичках, вы только себе жизнь усложняете (я про тот случай, когда оптимизация ухудшает читаемость\простоту использования кода).
по-моему, уходя от преждевременной оптимизации вы сваливаетесь в преждевременную пессимизацию. чем передача по ссылке усложняет жизнь или ухудшает читаемость кода? явно не тот случай.