【问题标题】:remove elements from structure从结构中删除元素
【发布时间】:2013-02-21 18:32:39
【问题描述】:

我有以下代码工作正常,除了当一个元素被删除时,它会从父结构中删除。我需要父母结构(first_name)与所有元素保持不变:

struct names_list {
    char username[20];
    struct names_list * next;
};
pthread_mutex_t name_list;

int retu = 0;
char username[20];
struct names_list * curr_name = first_name;
struct names_list * temp_name = NULL;
while( curr_name != NULL )
{
    pthread_mutex_lock(&name_list);
    strncpy(username, curr_name->username, sizeof( username ) - 1 );
    pthread_mutex_unlock(&name_list);
    //validate
    retu = validate_name(sock,buff,sizeof(buff),username,domain);
    switch ( retu )
    {
    case 0:
        pthread_mutex_lock(&name_list);
        if (temp_name == NULL)
             first_name = curr_name->next;  //this is used for removing when current is first record
        else
            temp_name->next = curr_name->next; //this is used for removing current record from mid-list

        free(curr_name);//Freeing should be needed
        curr_name = curr_name->next;
        pthread_mutex_unlock(&name_list);
        break;

    case 1:
        pthread_mutex_lock(&name_list);
        temp_name = curr_name;
        curr_name = curr_name->next;
        pthread_mutex_unlock(&name_list);
        break;
    }

    if (retu == 2)
        break;
}

pthread_mutex_lock(&name_list);
curr_name = first_name;
pthread_mutex_unlock(&name_list);

*如何仅从 curr_name 中删除元素并将原始结构保留在 first_name 中?*

【问题讨论】:

  • curr_name = curr_name->next; 紧跟在free(curr_name); 之后是未定义的行为。除此之外,first_name 是什么,validate_name 是做什么的?
  • validate_name 返回 0 或 1,与此问题无关。我的问题与结构以及我发布时如何处理它们有关
  • “在 first_name 中保留原始结构”到底是什么意思,您希望删除后剩余项目的 Head 由 first_name 指向吗?
  • 如果validate_name返回0,那么应该删除当前列表元素,对吗?再说一次,first_name 是什么?全局、函数参数还是什么?
  • 我需要包含所有元素的 first_name 结构和另一个(curr_name)结构,它是 first_name 的副本,以删除无效名称。所以最后我需要一个包含所有元素(first_name)和一个包含有效元素(curr_name)的结构。现在代码从 first_name 中删除了无效元素,这是错误的

标签: c struct pthreads


【解决方案1】:

这是您的解决方案。

struct names_list {
        char username[20];
        struct names_list * next;
};
pthread_mutex_t name_list;


int retu = 0;
char username[20];
struct names_list * temp_list_head=NULL;
struct names_list * prev_list_node=NULL;
struct names_list * curr_name = first_name;
struct names_list * temp_name = NULL;

//make a copy of your list
while (curr_name){
    struct names_list *tempNode = malloc(sizeof( struct names_list));
    *tempNode = *curr_name;
    if (temp_list_head== NULL)
        temp_list_head = tempNode;
    if (prev_list_node!=NULL)
        prev_list_node->next = tempNode;
    prev_list_node = tempNode;
    curr_name = curr_name->next;
}

curr_name = temp_list_head;

while( curr_name != NULL )
{
    pthread_mutex_lock(&name_list);
    strncpy(username, curr_name->username, sizeof( username ) - 1 );
    pthread_mutex_unlock(&name_list);
    //validate
    retu = validate_name(sock,buff,sizeof(buff),username,domain);
    switch ( retu )
    {
       case 0:
         pthread_mutex_lock(&name_list);
         if (temp_name == NULL)
              temp_list_head = curr_name->next;  //this is used for removing when current is first record
         else
              temp_name->next = curr_name->next; //this is used for removing current record from mid-list
         free(curr_name);//Freeing should be needed
        // curr_name = curr_name->next; //not needed, its removed from the list
         pthread_mutex_unlock(&name_list);
         break;
       case 1:
         pthread_mutex_lock(&name_list);
         temp_name = curr_name;
         curr_name = curr_name->next;
         pthread_mutex_unlock(&name_list);
         break;
    }
    if (retu == 2)
         break;
}
pthread_mutex_lock(&name_list);
curr_name = temp_list_head;
pthread_mutex_unlock(&name_list);

【讨论】:

  • 是C,这里没有new,一定是malloc。而memcpy 应该使用sizeof *curr_name,但为什么不只使用*temp_node = *curr_name
  • C 的好调用,大脑睡着了。至于memcpy,你想要结构的大小不是吗?所以它应该是结构。 *curr_name 将是相同的东西,但不太明显,因为您应该使用带有 sizeof 的类型。你是对的,使用 = 运算符分配内存要简洁得多。如此编辑。谢谢!
  • 这会影响使用的速度或内存吗?我使用 malloc 将记录添加到 first_name 结构。有没有其他方法可以在不使用 malloc 的情况下复制结构?
  • 是的,它会影响性能。不,没有办法。您需要新列表的专用内存,因此您需要分配它。至于分配本身的性能,如果你想实现一个平板或池分配器,你可以优化它。然而,那是一个完全不同的问题。我会考虑这个程序的情况,以及对 malloc 的 X 多次调用是否会极大地影响整个应用程序的性能。
  • 您最初在memcpy 中有sizeof(curr_name),这是指针的大小,而不是结构的大小。我猜是错字。
猜你喜欢
  • 2017-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多