1

考虑以下代码片段

  struct node {
    char *name;
    int m1;
    struct node *next;
    };

    struct node* head = 0; //start with NULL list

    void addRecord(const char *pName, int ms1)
    {   
        struct node* newNode = (struct node*) malloc(sizeof(struct node)); // allocate node

        int nameLength = tStrlen(pName);
        newNode->name = (char *) malloc(nameLength);
        tStrcpy(newNode->name, pName);

        newNode->m1 = ms1;
        newNode->next = head; // link the old list off the new node
        head = newNode;
    }

    void clear(void)
    {
        struct node* current = head;
        struct node* next;
        while (current != 0) 
        {
            next = current->next; // note the next pointer
    /*      if(current->name !=0)
            {
                free(current->name);
            }
    */
            if(current !=0 )
            {
                free(current); // delete the node
            }
            current = next; // advance to the next node
        }
        head = 0;
    }

问题:我无法释放当前-> 名称,只有当我评论释放名称时,程序才能工作。如果我取消注释 current->name 的空闲部分,我的 Visual Studio 窗口中会出现堆损坏错误。我怎样才能免费名称?

回复:

@all,是的,结构声明中有错别字。应该是 char* 名称,然后是 struct node*。看起来 stackoverflow 编辑器拿走了那两颗星。

通过执行 malloc(nameLength + 1) 解决了该问题。但是,如果我尝试在命令提示符而不是在 Visual Studio 上运行旧代码 (malloc(namelength)),它运行良好。看起来,有些编译器在做严格的检查。

我仍然不明白的一件事是,free 不需要 NULL 终止指针,并且在这里覆盖分配的指针的机会非常小。

user2531639 又名 Neeraj

4

1 回答 1

7

这是写入超出分配内存的末尾,因为空终止字符没有空间,导致未定义的行为:

newNode->name = (char *) malloc(nameLength);
tStrcpy(newNode->name, pName);

纠正:

newNode->name = malloc(nameLength + 1);
if (newNode->name)
{
    tStrcpy(newNode->name, pName);
}

注意free()使用指针调用是安全的,因此在调用它之前NULL检查是多余的:NULL

free(current->name);
free(current);

此外,我假设发布的定义中有拼写错误struct(作为类型name并且next应该是指针):

struct node {
    char* name;
    int m1;
    struct node* next;
};
于 2013-06-28T11:32:30.203 回答