2013-06-13 3 views
0

Я запускаю ошибки сегментации при запуске этого кода (никаких предупреждений или ошибок компилятора). Это происходит при попытке присвоить «Тест» для str->sStringC++: доступ к элементам структуры с помощью указателя

MyClass.cpp 
//Constructor 
MyClass::MyClass(MyStruct *pDesc) 
{ 
    pDesc = new MyStruct(); 

    //This is where I get a segmentation fault 
    pDesc->bar= 0xFF; 

} 


MyClass.hpp 

class ClGadgetFs 
{ 
    public: 
      struct MyStruct{ 
     int bar; 
     }; 
     MyClass(MyStruct *pDesc = NULL); 
}; 

Я думал при вызове нового я бы aalocating памяти для структуры? Как malloc(sizeof(myStruct)) Где я ошибаюсь?

+1

Если вы передаете указатель, который уже действует, поэтому выделить память для него? – legends2k

+7

, пожалуйста, предоставьте реальный код, это не он. –

+3

Просьба представить полный, компилируемый и исполняемый пример, который отображает описанную вами проблему. –

ответ

2
void setStruct(myStruct*& str) 

Вышеупомянутое, вероятно, то, что вы хотите: изменение переданного указателя в качестве выходного параметра.

0
#include <string> 

struct myStruct 
{ 
    std::string sString; 
    int nNo; 
}; 


void setStruct(myStruct **str) 
{ 
    *str = new myStruct(); 
    (*str)->sString = "Test"; 
    (*str)->nNo = 4; 
} 

int main() 
{ 
    myStruct *p; 
    setStruct(&p); 
} 

должно быть то, что вы хотите, это C-стиль передачи указателя; поскольку вы выделяете память для пройденного указателя, передача указателя сама по себе не работает, вы должны передать адрес указателя. Другой способ - ссылка на указатель, который указывает answer Joop Eggen.

0

str в функции setStruct является локальной переменной, срок службы которой ограничен этой функцией.

Поэтому, когда new возвращает адрес, на фактический параметр не влияет. Это как раз то же самое

void func(int a){ 
    a = 4 
} 

Вы должны использовать указатель на указатель или ссылку

void setStruct(myStruct ** str){ 
    (*str) = new myStruct(); 
    (*str)->sString = "Test"; 
    (*str)->nNo = 4; 
} 

void setStruct(myStruct *& str){ 
    str = new myStruct(); 
    str->sString = "Test"; 
    str->nNo = 4; 
} 
0

Вполне вероятно, что вызывающий setStruct является выделение myStructна стеке:

myStruct value; 

и вы звоните setStruct(&value);

Это приведет к сбою сегментации, поскольку вы пытаетесь переупорядочить память стека. Трудно сказать что-нибудь еще без полного примера.

Нет ничего плохого в коде, поскольку он стоит в стороне от того факта, что значение указателя, следующего за str = new myStruct();, не передается обратно вызывающему абоненту: вызывающий объект все равно будет ссылаться на указатель, указывающий на нераспределенную память, что приведет к неопределенное поведение. Но это не, вызывающий ваш сбой с момента, когда вы говорите об ошибке.

Простое исправление было бы изменить прототип функции для

void setStruct(myStruct*& str) 

т.е. передать указатель по ссылке, так что звонящий получить'S измененное значение указателя обратно.

4
void setStruct(myStruct *str) 
{ 
    str->sString = "Test"; 
    str->nNo = 4; 
} 

int main() 
{ 
    myStruct p; 
    setStruct(&p); 
    return 0; 
} 

вы можете сделать это вместо того, чтобы

Редактировать

int main() 
{ 
    MyStruct *pDesc; 
    MyClass myClassInstance(pDesc); 
    std::cout<< pDesc->bar << std::endl; 
    return 0; 
} 

и

MyClass::MyClass(MyStruct *pDesc) 

должен быть изменен на

MyClass::MyClass(MyStruct *& pDesc) 
+1

Это чистое и означает, что вам не нужно беспокоиться о освобождении памяти. – Bathsheba

+0

plus, вы отправляете указатель только на класс, а не на всю структуру. – aah134

0

Вы должны использовать ссылку на указатель, чтобы изменить его в функции:

struct myStruct{ 
    std::string sStrnig; 
    int nNo; 
}; 


void setStruct(myStruct* &str){ 

    str = new myStruct(); 

    str->sString = "Test"; 
    str->nNo = 4; 
} 

main(){ 
    struct myStruct *str = 0; 
    setStruct(str); 
} 
Смежные вопросы