Ответы пользователя по тегу C++
  • Реализация класса "полином" с динамическим массивом?

    @Alexander1705
    float *k = new float[polynomsize];

    Вы переопределили k и присваиваете локальному указателю, а не полю.
    Ответ написан
  • С++ Как узнать подробности об ошибке?

    @Alexander1705
    greeting = " Hello!!!";
    result = strcat(greeting, name); // Сдесь программа вылетает

    Конечно же вылетает. Используйте std::string, или научитесь работать с указателями.

    Утечка памяти 1: CppHello::~CppHello() {}.
    Утечка памяти 2: name = value;.
    Утечка памяти 3: greeting = " Hello!!!";.
    Запись в защищённую область памяти: strcat(greeting, name);

    P. S. Segmentation fault не бросает исключения. Перехватить его можно, но не нужно. Отладчик покажет, где происходит segfault.

    P. P. S. Здесь подробнее про вашу ошибку: Writing to read-only memory
    Ответ написан
    Комментировать
  • Как с помощью make собрать исполняемый файл из 2-x исходников?

    @Alexander1705
    Как вам уже ответили в комментарии, вы просто не указали параметр для -o.
    cc -o tr main_0.o main_1.o

    Вообще, никогда не нужно использовать абсолютные пути в Makefile.
    И ещё, если вы поменяете свой header.h, то make об этом не узнает.
    У компиляторов есть специальные опции, чтобы сгенерировать зависимости .c файлов от заголовков.
    Вот вам универсальный Makefile для простых проектов:
    PROJECT = tr
    SOURCES = main_0.c main_1.c
    OBJECTS = $(SOURCES:.c=.o)
    HEADER_DEPS = $(SOURCES:.c=.d)
    
    .PHONY: all
    
    all: $(PROJECT)
    
    $(PROJECT): $(OBJECTS)
    	$(CC) $(CFLAGS) $^ -o $@
    
    -include $(HEADER_DEPS)
    
    %.o: %.c
    	$(CC) $(CFLAGS) -MM -MT $@ -MF $(patsubst %.o,%.d,$@) $<
    	$(CC) $(CFLAGS) -c $< -o $@
    
    .PHONY: clean
    
    clean:
    	$(RM) $(PROJECT) $(OBJECTS) $(HEADER_DEPS)
    Ответ написан
    3 комментария
  • Где в linux искать библиотеки для GCC?

    @Alexander1705
    Библиотеки обычно устанавливают в /usr/lib/, /usr/local/lib и их подпапки. Обычно эти пути и так находятся в LD_PATH, так что достаточно указать -l<libname>.

    Так же библиотеки часто устанавливаются вместе с pkg-config конфигурацией, так что можно использовать его так:
    gcc -c file.c `pkg-config --cflags <libname>`
    gcc file.o -o file `pkg-config --libs <libname>`
    Ответ написан
    Комментировать
  • Как собирать статические библиотеки из исходников?

    @Alexander1705
    У многих языков программирования системы сборки поставляются вместе с компиляторами и являються де-факто стандартом для соответсвующего языка.

    Для C/C++ де-факто стандрата сборки нет, но есть несколько систем сборки, которые обычно используються:

    make - очень простая утилита, но неудобно для больших проектов.
    Можно определить по наличию файла Makefile. Иногда этот файл генерируеться скриптом configure.
    Если есть Makefile, запускаем:
    $ make
    Удалить сгенерированные файлы (чтобы запустить сборку заново):
    $ make clean

    cmake- более высокоуровневая система сборки, генерирует проекты для IDE или те же Makefile.
    Можно определить по наличию CMakeLists.txt
    mkdir cmake-build
    # Создаём папку для сгенерированных файлов, чтобы не смешивались с исходниками
    # Это называеться out-of-source build
    cd cmake-build
    
    # Генерируем проект или Makefile
    cmake ..
    
    # Запускаем билд, можно просто запустить make
    cmake --build .


    qmake - система сборки разработаная для сборки Qt и проектов использующих Qt.
    Можно определить по наличию .pro файлов. Билдим так:
    qmake
    make


    В вашем случае используеться make.
    Ответ написан
    Комментировать
  • Как в С++ красиво вывести элементы vector в консоль / просто в поток?

    @Alexander1705
    template <typename container>
    void print(const container& c)
    {
      auto it = begin(c);
      while(it != end(c) && cout << *it++, it != end(c)) { cout << ", "; }
    }
    Ответ написан
    2 комментария
  • Как выполнить некоторый код при выходе из функции?

    @Alexander1705
    Можно воспользоватся деструктором. Не забывайте, что нельзя бросать исключения в деструкторе.
    #include <iostream>
    #include <functional>
    
    template <typename T>
    class defer {
    private:
        std::function<T()> mFunctor;
    public:
        defer(std::function<T()> functor) : mFunctor(functor) {}
        ~defer() { mFunctor(); }
    };
    
    int main() {
        defer<void> d([] { std::cout << "Deferred func!" << std::endl; });
        //...
        
        std::cout << "Hello, world!" << std::endl;
        
        if (true) {
            return 0;
        }
        //...
        if (false){
            return 1;
        }
        
        return 0;
    }
    Ответ написан
    3 комментария
  • В какой среде разрабатывают интерфейс для программ на C++?

    @Alexander1705
    Qt - не среда разработки, а фреймворк. Среды разработки это QtCreator, CLion, Visual Studio. Все они позволяют работать с Qt.
    Кроме Qt можете посмотреть на GTK+ (gtkmm), wxWidgets.
    Ответ написан
    Комментировать
  • Как происходит компоновка программы с библиотеками и как запустить эту программу на другом ПК?

    @Alexander1705
    Компоновка бывает как статическая, когда библиотека (.a или .lib) сразу добавляется в состав исполнимого файла, или динамическая, когда библиотека (.so или .dll) загружается перед запуском приложения.

    Во втором случае, библиотеки обычно устанавливаются пакетным менеджером, как зависимости проекта. Или же каким-либо инсталятором, если установка происходит на Windows.
    Ответ написан
  • Как сделать перегрузку конструктора без расширения типа?

    @Alexander1705
    Происходит это из-за расширения типа bool до int

    Это не так. int может быть приведён как к bool, так и к uint32_t. И компилятор не знает что именно вы имеете в виду. Достаточно явно привести аргумент к нужному типу, чтобы можно было однозначно определить, какой конструктор вы вызываете.

    CAttribute("name", (uint32_t)index, "value");
    Ответ написан
    Комментировать
  • Как устроена авторизация по паролю в web-приложениях?

    @Alexander1705
    Обычно разделяют сессии и авторизацию:

    Сессия. Чтобы реализовать сессии сервер при первом соединении с клиентом может генерировать некоторый случайный токен и устанавливать его в куки. Тут важно, что куки должны передаваться по защищённому каналу (HTTPS). Таким образом можно сохранять некоторую информацию о сессии в базе данных или же в самих куки, но тогда нужно подписывать куки, чтобы пользователь не мог их изменять.
    В любом случае, сервер будет хранить информацию о активных сессиях в БД.
    Подписать куки можно, например, добавив в них помимо нужной вам информации какой-нибудь HMAC.

    Авторизация. Сервер никогда не хранит пароли. В базе данных хранят логин и хеш пароля (на самом деле нет). Для авторизации пользовтель передаёт логин и пароль (HTTPS). Сервер вычисляет хеш от пароля и, если он совпадает, сессия помечается как авторизованная.

    Соль. Теперь представим, что вы действительно храните логин и хеш пароля в таблице:
    login | pass_hash
    ------+----------
    vasya | 4B32E1C...

    В идеальном мире это бы неплохо работало. Но в реальном мире 90% ваших пользователей будут иметь пароль вида 12345, password, password123, etc. Соответственно в базе данных будет много одинаковых хешей и злоумышленнику не составит труда быстро подобрать пароли большинства ваших пользователей.
    Для этого для каждого пользователя сервер сохраняет некоторые уникальные случайные данные (соль). А вместо хеша пароля хранится hash(pass + salt).
    login | salt   | hash
    ------+--------+-----
    vasya | 4B3... | 2A3B9...

    Таким образом усложняется перебор паролей по словарю.

    Хеш. Возможно вы где-то видели или слышали про MD5. Так вот, MD5 на сегодняшний день не является надёжной криптографической хеш функцией и даже если вы примените MD5 сто или тысячу раз, это не сильно изменит ситуацию. На сегодняшний день рекомендуется использовать SHA-2 или SHA-3.

    P. S. Соль и токены обязательно должны быть сгенерированы с помощью CSPRNG.
    Ответ написан
  • Почему вызывается исключение???

    @Alexander1705
    Вы не инициализируете контекст OpenGL, поэтому ваша программа падает при первом же использовании функции OpenGL. Для инициализации вам нужно использовать GLEW.

    Так же не понятно, зачем вы подключаете GLUT и GLFW одновременно...

    Посмотрите этот туториал по OpenGL. В конце статьи есть код, который делает как раз то, что вам нужно.

    P. S. Исключение, как собственно и написано, вызывается, когда программа разыменовывает (использует) указатель, который указывает на память за пределами адресного пространства приложения. Например, неинициализированный указатель.
    Ответ написан
    2 комментария
  • Как делать GLSL шейдеры???

    @Alexander1705
    GLSL шейдеры компилируются с помощью вашего драйвера при каждом запуске opengl приложения. Вам нужно передать ему исходный код с помощью соответствующих функций OpenGL.

    www.opengl-tutorial.org/beginners-tutorials/tutori...
    Ответ написан
    Комментировать
  • Как зашифровать строку c++?

    @Alexander1705
    Если важно, чтоб зашифрованную строку нельзя было расшифровать без ключа, используйте проверенные алгоритмы шифрования, например Salsa20.
    Ответ написан
    Комментировать
  • Изначальный массив обрезается после функции копирования почему?

    @Alexander1705
    #include <iostream>
    
    void encode(char *msg)
    {
        for (int i = 0; msg[i]; ++i)
        {
            msg[i] = 'z' - (msg[i] - 'a');
        }
    }
    
    int main()
    {
        char msg[] = "hello";
        encode(msg);
        std::cout << msg << std::endl;
    }


    P.S. Не используйте system("pause"). Это не предназначено для того, для чего вы его используете. И вообще никогда не должно использоваться.
    Ответ написан
  • Почему в gcc не подключается?

    @Alexander1705
    Библиотека != заголовочный файл.

    Заголовочный файл содержит только объявления (т.е. описания). Например:
    // time.h
    #ifndef TIME_H
    #define TIME_H
    double time(float x);
    #endif


    Реализация может быть в отдельном файле.
    // time.c
    #include "time.h"
    #include <math.h>
    
    double time(float x){
      return 5.0*sqrt(x*x + 36.0) + 4.0*(20.0 - x);
    }


    Чтобы каждый раз этот код не компилировать, можно скомпилировать его однажды в библиотеку:
    gcc -c time.c -o time.o # Создаём объектный файл (скомпилированый код)
    ar rcs libtime.a time.o # Создаём статическую библиотеку (по сути, архив объектных файлов)


    А потом только подключать её:
    gcc main.c -ltime

    // main.c
    #include <stdio.h>
    #include <math.h>
    #include "time.h"
    
    int main(){
      double l = 0;
      double r = 20;
      for(int i = 0; i < 1000; i++){
        double mid = (r+l)/2;
        double tl = mid - mid/10;
        double tr = mid + mid/10;
        if(time(tl) < time(tr))
          r = tr;
        else
          l = tl;
      }
      printf("x = %g;  t = %g\n", (l+r)/2, time((l+r)/2));
      return 0;
    }


    P.S. -l - сокращение от слова link (связывать).

    P.P.S. Разделение libc и libm сложилось по историческим причинам.
    Ответ написан
    5 комментариев
  • Как подключить LLVM в качестве C++ библиотеки?

    @Alexander1705
    1. Указать путь к заголовочным файлам.
    2. Указать путь и имя библиотеки.


    Детали могут отличаться в зависимости от вашей среды разработки. В visual studio должны быть настройки для этого. Если используете cmake, тогда используйте find_package, target_include_directories, target_link_libraries.
    Ответ написан
    Комментировать