Почему я не могу найти указатель на разыменованный символ? - PullRequest
0 голосов
/ 21 апреля 2020

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

main. cpp

#include <iostream>
#include <cstdio>
#include "colours.hpp"

using namespace std;

int main()
{
    colour co(50,65,78);
    unsigned char *cp = co.getRGB();
    cout << *cp << endl;
    getchar();
    return 0;
}

colours.hpp

#ifndef COLOURS
#define COLOURS

class colour{
    public:
        colour(unsigned char r, unsigned char g, unsigned char b);
        unsigned char *getRGB();
    private:
        unsigned char red, green, blue;
};

#endif // COLOURS

colors. cpp

#include "colours.hpp"

colour::colour(unsigned char r, unsigned char g, unsigned char b) : red(r), green(g), blue(b) {
}

unsigned char *colour::getRGB(){
    unsigned char arr[3] = {red, green, blue};
    return arr;
}

1 Ответ

2 голосов
/ 21 апреля 2020

Вы определили массив локально в стеке в следующей функции:

unsigned char *colour::getRGB(){
    unsigned char arr[3] = {red, green, blue};
    return arr;
}

Когда функция возвращается, стек уменьшается и массив больше не действителен (как указатель на массив). По этой причине ваша программа аварийно завершает работу при разыменовании указателя.

Чтобы решить эту проблему, вы можете использовать массив для цветов, так как вы знаете размер во время компиляции.

std::array<unsigned char, 3> colour::getRGB(){
    std::array<unsigned char, 3> color = {red, green, blue};
    return color;
}

Другой альтернативой является выделение в куче вместо стека

unsigned char* colour::getRGB() {
    int size = sizeof(unsigned char) * 3;  // Get the size of 3 unsigned chars.
    unsigned char* color = (unsigned char*) malloc(size);
    color[0] = red;
    color[1] = green;
    color[2] = blue;

    return color;
}

Этот метод имеет несколько недостатков. Во-первых, вы должны помнить, чтобы освободить память, выделенную вам, когда закончите с ней.

colour a = colour(255, 0, 255);
unsigned char* rgb = a.getRGB();
// ---- DO STUFF ---
free(rgb);

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

В-третьих, поскольку мы уже знаем, что хотим иметь 3 неподписанных символа, динамическое выделение не требуется. Это исключает возможность того, что компилятор выполнит stati c анализ и оптимизацию кода.

...