释放动态数组char时崩溃

时间:2017-06-09 20:41:41

标签: 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);
}

1 个答案:

答案 0 :(得分:5)

createStudent这一行:

s->name = (char*)malloc(sizeof(name) + 1);

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

修正:

s->name = malloc(strlen(name) + 1);

或替换这两行:

s->name = (char*)malloc(sizeof(name) + 1);
strcpy(s->name, name);

通过

s->name = strdup(name);

处理分配&正确复制。

注意:因为它是C ++代码,所以最好使用std::string来处理字符串。你可以节省大量的时间来追捕崩溃事件。内存泄漏。