Проблемы с пониманием указателей с выделением памяти Dynami c - PullRequest
0 голосов
/ 03 августа 2020

Я пытаюсь сделать здесь что-то очень конкретное c и понимаю, что, по-видимому, не знаю, что делаю. Я не решаюсь спрашивать об этом сообщество, потому что подозреваю, что большинство экспертов по C ++ будут недовольны мной и рекомендуют использовать std :: array или std :: vector или выбрать другую карьеру. При этом я хотел бы просто понять, почему то, что я пытаюсь сделать ниже, работает в двух случаях, но не в третьем. Если я смогу понять основную проблему, это поможет мне в будущем.

Мне нужно, чтобы моя main () вызывала функцию функции класса и чтобы эта функция возвращала указатель на динамически выделяемый массив введите uint8_t. Функция main () не знает априори размер динамически выделяемого массива; все, что он знает, это то, что он получит указатель на массив типа uint8_t. В приведенном ниже примере давайте проигнорируем важность того, что функция, возвращающая указатель, также вернет размер выделенного ею массива ... предположим, что я делаю это в своем реальном коде.

Я пытаюсь понять, почему следующие вызовы устанавливают mainsMyPointerC на NULL:

myClassObj.MyFuncB(mainsMyPointerC);

Вот код ниже.

#include <iostream>
using namespace std;

class MyClass {
    public:

        uint8_t* MyFuncA(void)  //This works
        {
            //Let's say MyFuncA does something smart and figures out it needs a byte array of size 100
            uint16_t size = 100u;

            uint8_t* tempPointer = new uint8_t[size];
            tempPointer[0]   = 101;
            tempPointer[1]   = 102;
            tempPointer[99]  = 103;

            return tempPointer;
        }

        void MyFuncB(uint8_t* myPointer)
        {
            //Let's say MyFuncB does something smart and figures out it needs a byte array of size 100
            uint16_t size = 100u;

            uint8_t* tempPointer = new uint8_t[size];
            tempPointer[0]  = 201;
            tempPointer[1]  = 202;
            tempPointer[99] = 203;

            myPointer = tempPointer;
        }
};

int main() {

    //main() can't know apriori how big a dynamically allocated array from MyFuncA or MyFuncB will be...
    uint8_t* mainsMyPointerA = NULL;
    uint8_t* mainsMyPointerC = NULL;

    //... but let's say it could for this one case.
    uint8_t* mainsMyPointerB = new uint8_t[100];  //this also works: new uint8_t[50]

    MyClass myClassObj;

    //##############  This works  #####################
    mainsMyPointerA = myClassObj.MyFuncA();
    printf("Is mainsMyPointerA NULL ? [%s]\n", (mainsMyPointerA == NULL) ? "YES" : "NO");
    printf("mainsMyPointerA[0]  = %u\n", mainsMyPointerA[0]);
    printf("mainsMyPointerA[1]  = %u\n", mainsMyPointerA[1]);
    printf("mainsMyPointeRA[99] = %u\n", mainsMyPointerA[99]);
    delete [] mainsMyPointerA;
    printf("mainsMyPointerA is deleted\n\n");

    //##############  This works  #####################
    myClassObj.MyFuncB(mainsMyPointerB);
    printf("Is mainsMyPointerB NULL ? [%s]\n", (mainsMyPointerB == NULL) ? "YES" : "NO");
    printf("mainsMyPointerB[0]  = %u\n",  mainsMyPointerB[0]);
    printf("mainsMyPointerB[1]  = %u\n",  mainsMyPointerB[1]);
    printf("mainsMyPointerB[99] = %u\n",  mainsMyPointerB[99]);

    delete [] mainsMyPointerB;
    printf("mainsMyPointerB is deleted\n\n");

    //##############  This fails  #####################
    myClassObj.MyFuncB(mainsMyPointerC);
    printf("Is mainsMyPointerC NULL ? [%s]\n", (mainsMyPointerC == NULL) ? "YES" : "NO");  //<<-- Why is mainsMyPointerC NULL here?
    printf("mainsMyPointerC[0]  = %u\n",  mainsMyPointerC[0]); //<<-- Crash occurs here... but why?
    printf("mainsMyPointerC[1]  = %u\n",  mainsMyPointerC[1]);
    printf("mainsMyPointerC[99] = %u\n",  mainsMyPointerC[99]);

    //I expected mainsMyPointerC to point to the first element in the dynamically allocated memory after call MyFuncB... but it's NULL instead

    delete [] mainsMyPointerC;
    printf("mainsMyPointerC is deleted\n\n");

}

Любая помощь в объяснении, почему первые два вызова работают, а третий не приветствуется.

Кроме того, "безопасно" ли выполнить первый вызов или это фейспалм?:

mainsMyPointerA = myClassObj.MyFuncA();
...