释放动态数组char时崩溃

Can*_*tin 1 c++

当我尝试在dequeue()函数中为Student的name字段释放char数组时,程序崩溃了.内存先前已在createStudent()函数中分配.

我真的看不出我想念的东西.

#include "iostream"
#include "stdio.h"
using namespace std;

struct Student
{
    int id;
    char* name;
};

struct QueueNode
{
    Student* info;
    QueueNode* next;
};

Student* createStudent(int id, char* name)
{
    Student* s = (Student*)malloc(sizeof(Student));
    s->id = id;
    s->name = (char*)malloc(sizeof(name) + 1);
    strcpy(s->name, name);

    return s;
}

QueueNode* createQueueNode(Student *s)
{
    QueueNode *queue = (QueueNode*)malloc(sizeof(QueueNode));
    queue->info = s;
    queue->next = nullptr;

    return queue;
}

void enqueueNode(QueueNode* &root, QueueNode* node)
{
    if (root == nullptr)
        root = node;
    else
    {
        QueueNode* tmp = root;
        while (tmp->next)
            tmp = tmp->next;
        tmp->next = node;
    }
}

Student* dequeueNode(QueueNode* &root)
{
    Student* s = nullptr;
    if (root != nullptr)
    {
        QueueNode* tmp = root;
        s = tmp->info;
        root = root->next;
        free(tmp->info->name);    ----->>program crashes
        free(tmp->info);
        free(tmp);
    }
    return s;
}

void printqueue(QueueNode* root)
{
    if (root)
    {
        printf("Id:%d Name:%s\n", root->info->id, root->info->name);
        printqueue(root->next);
    }
}

void main()
{

    FILE* file = fopen("Text.txt", "r");
    int id; char buffer[50];
    QueueNode* queue = nullptr;

    fscanf(file, "%d", &id);
    while (!feof(file))
    {
        fgetc(file);
        fscanf(file, "%[^\n]s", buffer);
        Student* s = createStudent(id, buffer);
        QueueNode* node = createQueueNode(s);
        enqueueNode(queue, node);
        fscanf(file, "%d", &id);
    }
    dequeueNode(queue);
    printqueue(queue);
}
Run Code Online (Sandbox Code Playgroud)

Jea*_*bre 5

createStudent这一行:

s->name = (char*)malloc(sizeof(name) + 1);
Run Code Online (Sandbox Code Playgroud)

分配指针的大小+ 1,而不是指向的字符串的大小name(sizeof这里误用).因此,您正在破坏内存列表,并且在释放它时会看到,因为您之前通过为分配的缓冲区复制字符串太长而触发了未定义的行为(尽管可能看起来使用短字符串).

固定:

s->name = malloc(strlen(name) + 1);
Run Code Online (Sandbox Code Playgroud)

或者替换这两行:

s->name = (char*)malloc(sizeof(name) + 1);
strcpy(s->name, name);
Run Code Online (Sandbox Code Playgroud)

通过

s->name = strdup(name);
Run Code Online (Sandbox Code Playgroud)

正确处理分配和复制.

注意:因为它是C++代码,所以最好std::string处理字符串.您将节省大量时间来查找崩溃和内存泄漏.