在struct C++中使用char*或char []

Eng*_*999 3 c++ string struct

我正在创建一个struct名为student.为了存储名称,仅仅char在具有预定义大小structchar数组中声明指针是否有任何问题?然后我可以将一个字符串文字分配给char主代码中的指针.

struct student
{
    int ID;
    char* name;
};
Run Code Online (Sandbox Code Playgroud)

Com*_* 10 7

不要使用,使用std::string.我(和许多其他)保证相比,无论char*char[]:

  1. 它会更容易使用和
  2. 它不会容易出错.


Vin*_*y99 6

这实际上取决于您的用例。如上所述,您应该std::string在 C++ 中使用。但如果您使用的是 C 风格的字符串,那么这取决于您的用法。

使用定义大小的char[]可以避免由于空指针和其他与指针相关的错误(例如内存泄漏、悬空指针等)而导致的错误,但您可能无法最佳地利用内存。例如,您可以定义

#define MAX_SIZE 100
struct student
{
    int ID;
    char name[MAX_SIZE];
};
Run Code Online (Sandbox Code Playgroud)

进而

#define STUDENT_COUNT 50
struct student many_students[STUDENT_COUNT];
Run Code Online (Sandbox Code Playgroud)

但学生姓名的长度会有所不同,并且在许多情况下远小于 MAX_SIZE。因为这里会浪费这么多内存。或者在某些情况下它可能大于 MAX_SIZE。您可能必须截断此处的名称以避免内存损坏。

在我们定义 use char* 的其他情况下,内存不会浪费,因为我们只分配所需的量,但我们必须处理内存分配和释放。

struct student
{
    int ID;
    char *name;
};
Run Code Online (Sandbox Code Playgroud)

然后在存储名称时我们需要执行以下操作:

struct student many_student[STUDENT_COUNT];
int i;
for( i=0; i<STUDENT_COUNT; i++) {
    // some code to get student name
    many_student[i].name = (char*)malloc(name_length+1 * sizeof(char));
    // Now we can store name
}

// Later when name is no longer required free it
free(many_student[some_valid_index_to_free].name);
// also set it to NULL, to avoid dangling pointers
many_student[some_valid_index_to_free].name = NULL;
Run Code Online (Sandbox Code Playgroud)

此外,如果您再次为 name 分配内存,则应该释放先前分配的内存以避免内存泄漏。另外要考虑的另一件事是在使用前对指针进行 NULL 检查,即,您应该始终检查为

if(many_students[valid_index].name!=NULL) {
    // do stuff
}
Run Code Online (Sandbox Code Playgroud)

尽管您可以创建宏来执行此操作,但这些都是指针的基本开销。

使用指针的另一个优点是,如果有许多相似的名称,那么您可以将多个指针指向相同的名称并节省内存,但在数组中,您将拥有单独的内存,例如,

// IF we have a predefined global name array
char *GLOBAL_NAMES[] = {"NAME_1", "NAME_2", "NAME_3", "NAME_4", ... , "NAME_N"};


// using pointers, just need to assign name to correct pointer in array
many_student[valid_index_1].name = GLOBAL_NAMES[INDEX_NAME_1];
many_student[valid_index_2].name = GLOBAL_NAMES[INDEX_NAME_1];

// In case of array we would have had to copy.
Run Code Online (Sandbox Code Playgroud)

虽然这可能不是你的情况,但只是说指针可能有助于避免额外的使用。

希望它能帮助你:)


rav*_*avi 5

差异与静态和动态内存分配之间的差异相同.对于前者(静态),您必须指定足以存储名称的大小,而后者则必须注意在不需要时删除它.

尽管使用它总是更好std::string.