简体   繁体   English

指向成员是指针的结构的c ++指针

[英]c++ pointer to a Structure whose member is a pointer

Hi all I am working on an assignment , when given a struct and its members I will have to intialise the members using dynamic memory allocation . 大家好,我正在做一个分配,当给定一个结构及其成员时,我将不得不使用动态内存分配来初始化这些成员。 This is the code I have used: 这是我使用的代码:

# include <iostream>
# include <string>

using namespace std;

Structure 结构体

struct Student
{
char * name;
float gpa;
} ;

PROTOTYPES 原型

Student *  createStudent(char name[], float gpa);

int main ()
{
 int length ;
 float gpa ;
 char *p;
 Student *myPointer ;
 Student myStudent ;
 myPointer = &myStudent;

 cout << " Please enter number of characters you want to enter " << endl;
 cin >> length ;
 length = length + 1;
 p= new char [length +1];
 cout << " Please enter name " << endl;
 cin >> p ;
 cout << " please enter gpa "<< endl;
 cin >> gpa ;
 myPointer = createStudent (p,gpa);
 cout << myPointer->gpa;
 cout << (*myPointer).name << endl;

Her's the error when printing the name, but when i see the value of the name before printing it is showing the same as entered by the user: 她是打印名称时的错误,但是当我在打印之前看到名称的值时,它显示的与用户输入的相同:

  delete[]p;
  p = 0;
  system("pause");
  return 0;
 }

This function creates a student object and assigns name and gpa as passed to the student object and returns a pointer of the student object: 此函数创建一个学生对象,并分配传递给该学生对象的名称和gpa,并返回该学生对象的指针:

Student *  createStudent( char name[], float gpa )
{

Student *studentPtr ;
Student studentObject;
studentPtr = &studentObject;
studentPtr-> name = name;
studentPtr-> gpa = gpa ;
return studentPtr ;
}

Can anyone give me an idea of why the name is not printing. 谁能给我一个为什么不打印名称的想法。 Thank you in advance . 先感谢您 。

studentObject is allocated on the stack, ie it has automatic storage duration, which means it will be destroyed when the function returns. studentObject是在堆栈上分配的,即它具有自动存储时间,这意味着函数返回时它将被销毁。 The pointer doesn't keep it alive. 指针不能使它保持活动状态。

That means myPointer is a dangling pointer; 这意味着myPointer是一个悬空指针; dereferencing it ( myPointer-> ) invokes undefined behavior. 取消引用( myPointer-> )会调用未定义的行为。


To correct it, simply return the object by value: 要更正它,只需按值返回对象:

Student createStudent(char name[], float gpa)
{
    Student studentObject;
    studentPtr.name = name;
    studentPtr.gpa = gpa;
    return studentObject;
}

and

Student myStudent = createStudent(p, gpa);

Edit: I just read that you need to initialize the members using dynamic memory allocation. 编辑:我刚刚读到您需要使用动态内存分配来初始化成员。 The above solution doesn't do that. 上面的解决方案没有做到这一点。 For dynamic memory allocation you have to use new : 对于动态内存分配,您必须使用new

Student* createStudent(char name[], float gpa)
{
    Student* studentPtr = new Student;
    studentPtr->name = name;
    studentPtr->gpa = gpa;
    return studentPtr;
}

and

myPointer = createStudent(p, gpa);
// use
delete myPointer;

It would probably be a good idea to also allocate a new buffer for studentPtr->name with new , instead of just assigning the pointer; 最好还为带有new studentPtr->name分配一个新缓冲区,而不只是分配指针。 you can see Mateusz 's answer about that. 您可以看到Mateusz的答案。

But of course this is just a bad example from your professor. 但这当然只是您教授的一个不好的例子。 As mentioned by gd1 , this kind of code is not good modern C++ and shouldn't end up in real production code. 正如gd1所提到的那样 ,这种代码不是现代的C ++好代码,并且不应最终出现在实际的生产代码中。

This is totally wrong: 这是完全错误的:

Student* createStudent( char name[], float gpa )
{
    Student *studentPtr ;
    Student studentObject;
    studentPtr = &studentObject;
    studentPtr-> name = name;
    studentPtr-> gpa = gpa ;
    return studentPtr ;
}

studentObject is a local object, that is destroyed just after the function ends. studentObject是一个本地对象,函数结束后即被销毁。 Returning pointers and/or references to local variables is an error - you should get warning from your compiler. 返回指针和/或对局部变量的引用是一个错误-您应该从编译器得到警告。

Another issue is this line: 另一问题是此行:

studentPtr->name = name;

What you do now: allocate a block of memory in main() , pass it to an object, that may use this memory and then free it in main() . 现在的操作:在main()分配一块内存,将其传递给可能使用该内存的对象,然后在main()释放它。 You should not do that - objects should be responsible for their content. 您不应该那样做-对象应该对其内容负责。 Are you sure, that this responsibility should be yours? 您确定此责任应该由您承担吗? I would suggest you to: 我建议您:

Student* createStudent( char name[], float gpa )
{
    size_t name_len = strlen(name);
    Student studentObject;
    studentObject.name = new char[name_len+1];
    strncpy(studentObject.name, name, name_len + 1);
    studentObject.gpa = gpa ;
    return studentObject;
}

And analogical function to destroy Student : 并具有破坏Student类比功能:

void destroyStudent(Student* student)
{
    delete[] student->name;
    student->name = nullptr;
}

Obvious solution would be to use std::string , but I assume, that you have a good reason to do all this manually... don't you? 显而易见的解决方案是使用std::string ,但是我认为您有充分的理由手动执行所有操作……不是吗?

Oh, and if you really need to return Student as pointer: 哦,如果您确实需要将Student作为指针返回:

Student* createStudent( char name[], float gpa )
{
    size_t name_len = strlen(name);
    Student* studentPtr = new Student;
    studentPtr->name = new char[name_len+1];
    strncpy(studentPtr->name, name, name_len + 1);
    studentPtr-> gpa = gpa ;
    return studentPtr;
}

void destroyStudent(Student* student)
{
    delete[] student->name;
    student->name = nullptr;
    delete[] student;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM