C语言 free() 处的分段错误



当我在以下链表实现的删除函数中执行free()时,我遇到了分割错误。请看一看,告诉我哪里出错了。当我使用 valgrind 运行这个程序时,没有 seg。故障,它运行正常。所以我无法弄清楚问题所在。

typedef struct node {
    char name[100];
    int id;
    struct node* next;
} Node;
void insert(Node** p, char* _name, int _id)
{
    Node *temp, *prev;
    temp = malloc(sizeof(struct node));
    temp->next = NULL;
    strcpy(temp->name,_name);
    temp->id = _id;
    if(*p == NULL) {
            *p = temp;
    }
    else {
            for(prev = *p; prev->next!=NULL; prev=prev->next);
            prev->next=temp;
    }
}
/* Delete entry
  @params p    first element
       _id     ID to delete
*/
void delete_by_id(Node** p, int _id) {
    Node *temp, *prev;
    prev = NULL;
    for(temp = *p; temp!= NULL; prev = temp, temp=temp->next) {
            if(temp->id == _id) {
                printf("Deleting entry with id: %dn", temp->id);
                if(prev == NULL)
                     *p = temp->next;
                else
                     prev->next= temp->next;
                free(temp);
                return;
            }
    }     
}

以下是主程序的部分代码:

Node* p;  
int main() {
      ...
      ...
      buf[rval]=0;
      char* tokens = strtok(buf, "+");
      char* strArray[5]; /* up-to 5 words can be stored */
      int n = 0;
      while (tokens)
      {
        strArray[n] = malloc(strlen(tokens) + 1);
        strcpy(strArray[n++], tokens);
        tokens = strtok(NULL, "+");
      }
      int type = 0;
      if(strcmp(strArray[0], "1") == 0)
            type = 1;
      else
            type = 2;
      char* name = "";  
      if(type == 1) {
            name = strArray[1];
            insert(&p, name, clients[i]);
            display(&p);
      } else {
            name = strArray[1];
            rval = search(&p, name);
            if(rval) { 
                delete_by_id(&p, rval);
                display(&p);
            }
      }
      for (i = 0; i < 5; i++)
      {
        if (strArray[i]) // check for null data 
            free(strArray[i]);
      }
      ...
      ...
}
int search(Node** p, char* _name) {
    Node *temp;
    for (temp = *p; temp!= NULL; temp = temp->next) {
            if (strcmp((char *)temp->name, _name)==0) {
                    printf("Name matched: %sn", temp->name);
                    return temp->id;
            }
    }
    return 0;
}

Valgrind抱怨malloc和free用于strArray,而不是链表。

打印出malloc()返回的地址,并在调用free()之前打印出temp的值。 确保传递给free()的内容符合您的预期。 如果您以某种方式传递指向不是来自malloc() free()的指针,您可能会遇到您所看到的问题。

函数 delete_by_id() 也可能使用无效指针。 p参数在检查NULL之前被取消引用。 我建议在调试器中遍历该函数,并确保所有指针的外观都符合您的预期。

让你的程序转储核心并在 GDB 中分析核心:

gdb -c yourprog.core yourprog

然后执行完整的回溯:

(gdb) bt full

这将显示段错误的确切原因以及传递给函数的值。

(编辑)哦,使用GCC -g开关编译程序以获得调试信息。

通过 valgrind 运行你的程序。空闲的隔离错误通常是由于在分配的内存之外的写入(这会覆盖/损坏系统在分配内存之前/之后放置的包装器)。瓦尔格林德通常是找出有问题的写作何时发生的最简单方法。

相关内容

  • 没有找到相关文章

最新更新