动态内存分配给结构类型

时间:2018-11-14 06:12:40

标签: c++

我正在尝试动态分配内存以进行结构化,但是在动态分配内存时出现错误

#include <string>

using namespace std;

#define MAX_GRADES 5

typedef struct _Student
{
    string id;
    string name;
    double grades[MAX_GRADES];
    double average;
}Student;

Student *update_list;

int main()
{
    Student *n = (*Student) malloc(sizeof(n));
    return 0;
}
main.cpp: In function ‘int main()’:
main.cpp:26:24: error: expected primary-expression before ‘)’ token
  Student *n = (*Student) malloc(sizeof(Student));
                        ^

6 个答案:

答案 0 :(得分:4)

TL; DR版本

使用

Student *n = new Student;

代替

Student *n = (*Student) malloc(sizeof(n));

说明

这是一个错字

Student *n = (*Student) malloc(sizeof(n));
              ^ wrong side.

你想要

Student *n = (Student*) malloc(sizeof(n));
                     ^ needs to be here.

这将编译。通常,我会发表评论并投票关闭,但是在运行时您会发现此解决方案有两个问题。

  1. n是一个指针。 sizeof(n)的指针大小保证比string短(除非string实现非常棒,并且无法执行我想不到的事情)。如果下一点并没有使该点变得无用,您将希望sizeof(*n)获得Student的大小。
  2. std::string是一个相当复杂的类。仅在其许多构造函数中的至少一个成功初始化该类的情况下才有效。 malloc是C函数。 C不知道什么是构造函数,因此没有运行string构造函数。这使得idname滴答作响的定时炸弹正等着炸毁您的程序。除非您知道该类是POD type或将在使用前使用placement new,否则不要malloc使用C ++类。

在此处使用new或根本不进行动态分配。

答案 1 :(得分:3)

  

学生* n =(*学生)malloc(sizeof(n));

(*Student)不是一种类型,您需要(Student*)。另外,sizeof n给出了系统上指针的大小,而不是一个或多个Student所需的大小。正确方法:

Student *n = (Student*) malloc(sizeof(*n));

但是,正如在user4581301的答案中指出的那样,您的Student不是POD,因此必须使用new以确保构造函数被调用:

Student *n = new Student;

或者,如果您想要多个Student

Student *n = new Student[42];

请记住,使用new分配的所有内存必须使用delete释放,使用new[]分配的所有内存必须与delete[]释放。

但是使用原始拥有的指针被认为是不好的做法,应避免使用std::unique_ptr<>std::shared_ptr<>之类的智能指针或容器:

C ++方式将使用std::vector<Student>
而且,没有理由在C ++中将typedef用于struct ure。

答案 2 :(得分:1)

您的代码中存在三个错误:

  • malloc之前的强制类型转换应为(Student *):这是n的正确类型,即指向Student的指针。
  • 要分配的大小为sizeof(Student)sizeof(n)会给您一个指针的大小,对于Student来说可能太小了。
  • 最重要:永远不要使用malloc为包含诸如string之类的复杂对象的结构分配内存。您必须改为使用new,请参阅讨论here

正确的密码是

#include <string>

using namespace std;

#define MAX_GRADES 5

struct Student
{
    string id;
    string name;
    double grades[MAX_GRADES];
    double average;
};

Student *update_list;

int main()
{
    Student *n = new Student;

    delete n;
    return 0;
}

我在末尾添加了delete n:不一定要正确运行代码,但是最好不要忘记删除分配的内存。

更好的是,与其使用#define来固定数组grades的大小,还不如使用模板参数:这样,MAX_GRADES不会在以下所有代码中传播。最后,通常最好避免在标头部分使用using namespace std;。这是因为,如果您曾经将Student的声明拆分到一个单独的头文件中,则每个包含该头文件的代码文件都会“继承” using namespace std;,这有可能与其他包含在头文件中的文件冲突。标头。

总而言之,您的代码的更好版本是

#include <string>

template <unsigned int MAX_GRADES>
struct Student
{
    std::string id;
    std::string name;
    double grades[MAX_GRADES];
    double average;
};

Student<5> *update_list;

int main()
{
    Student<5> *n = new Student<5>;

    delete n;
    return 0;
}

答案 3 :(得分:0)

问题出在代码的这一部分:

int main()
{
   Student *n = (*Student) malloc(sizeof(n));
   return 0;
}

理解'*'运算符是C ++中的间接运算符,将有助于识别问题。 https://msdn.microsoft.com/en-us/library/caaw7h5s.aspx

您不是要提取Student结构的值,而是要键入从void *返回的强制转换malloc。正确的方法是:

Student *n = new Student(正确的C ++处理方式-使用new运算符)

这将为您提供动态创建的Student结构的指针。如果打算创建Student的动态数组,则可以执行以下操作:

Student *n = new Student[5]

根据您的使用情况,您可能需要考虑一种简单的C ++ STL方式:std::vector<Student>std::list<Student>

在C ++中查找STL(标准模板库),您应该可以获得更多详细信息。

答案 4 :(得分:-2)

如果您使用的是c ++,请在可以使用“ new”的情况下不要使用“ malloc”分配内存:

Student* student = new Student();

除了分配空间外,“ new”还将调用结构的构造函数,该构造函数将允许初始化。语法也不太容易出错。

您还会注意到我的变量命名。在我的示例中,我选择“学生”而不是“ n”,因为它对读者更具描述性。

答案 5 :(得分:-2)

Student *n = (*Student) malloc(sizeof(n));
  1. malloc()返回点类型“ void *”,应转换为所需的类型,“ n”的类型为“ Student *”,而不是“ * Student”。
  2. malloc()的参数是内存字节。 sizeof()是用于在C ++中计算字节的运算符,您应在此处使用sizeof(Student)。 我建议使用此行:

    学生* n =(学生*)malloc(sizeof(学生));