Как добавить данные в массив указателей? - PullRequest
0 голосов
/ 13 января 2019

Я создал массив указателей. Я хочу знать, как prp = operly добавить данные в мой массив указателей. Я попытался код ниже, к сожалению, это дает мне ошибку памяти, и я не знаю, почему.

class dataClass {
    int data;
public:

    void setdata(int d) {data = d;}
    int getdata() const {return data;}
};

int main() {
    dataClass** ptr = new dataClass*s[5];

    int num = 9;
    ptr[0] -> setdata(num);

    return 0;
}

Ответы [ 3 ]

0 голосов
/ 13 января 2019

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

Например, используя 5 указатели при попытке задать свои вопросы, вам сначала нужно будет выделить указатели, например,

#define NPTRS 5
...
    dataClass** ptrs = new dataClass *[NPTRS];

Теперь у вас есть память, выделенная для 5 указателей на тип dataClass с адресом для начального указателя, назначенным для ptrs (для ясности я добавил форму множественного числа)

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

     for (int i = 0; i < NPTRS; i++) {
        ptrs[i] = new dataClass;
        ptrs[i]->setdata (i+1);
    }

(выше вы выделяете память для каждого экземпляра класса, присваивая результат ptrs[i], а затем устанавливаете значение data на i+1)

В целом, вы можете сделать что-то похожее на:

#include <iostream>
#include <cstdlib>

#define NPTRS 5

class dataClass {
    int data;
public:

    void setdata(int d) {data = d;}
    int getdata() const {return data;}
};

int main() {

    dataClass** ptrs = new dataClass *[NPTRS];

    for (int i = 0; i < NPTRS; i++) {
        ptrs[i] = new dataClass;
        ptrs[i]->setdata (i+1);
    }

    for (int i = 0; i < NPTRS; i++)
        std::cout << "ptrs[" << i <<"]->getdata() : " 
                << ptrs[i]->getdata() << '\n';

    return 0;
}

( примечание: не забывайте, что вы несете ответственность за отслеживание того, что вы выделили, и звоните delete, чтобы освободить каждое выделение, когда оно больше не нужно)

Пример использования / Вывод

$ ./bin/dblptr2class
ptrs[0]->getdata() : 1
ptrs[1]->getdata() : 2
ptrs[2]->getdata() : 3
ptrs[3]->getdata() : 4
ptrs[4]->getdata() : 5

Как уже упоминалось, контейнеры C ++, такие как vector, менее подвержены ошибкам и значительно облегчают вашу работу. Тем не менее, вы должны знать, как обращаться с new/delete, а также с использованием контейнеров.

Посмотрите вещи и дайте мне знать, если у вас есть дополнительные вопросы.

0 голосов
/ 13 января 2019

Вы можете сначала создать массив объектов (конструкторы будут вызываться автоматически).

После этого создайте указатель на указатель:

#include <stdio.h>

class dataClass {
    int data;
public:

dataClass(){ 
    printf(" new instance \n");
}

void setdata(int d) {
    data = d;
    printf(" setdata \n");
}

int getdata() const {return data;}
};

int main() {
    dataClass*  ptr = new dataClass[5];
    dataClass** pptr = &ptr;  

int num = 9;
pptr[0]->setdata(num);

return 0;
}

результат:

новый экземпляр
новый экземпляр
новый экземпляр
новый экземпляр
новый экземпляр
SetData

0 голосов
/ 13 января 2019

Вы просто выделяете память для указателей (не для объектов), поэтому ptr [0] указывает на неуказанный адрес, и вы получаете ошибку сегмента. Вам нужно добавить что-то вроде этого:

for(int i = 0; i < 5; i++) {
    ptr[i] = new dataClass;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...