删除链接列表元素

时间:2012-12-06 10:57:24

标签: c linux linked-list

我很好奇我做错了什么,因为我的void *DeleteDoneNodes(node * n)没有做任何事情,没有错误但没有更好的输出,所以任何人都可以帮助我找到问题的根源谢谢你。

场景:cmd行./s m n m列表中的n个节点数,node->value == 1 workingThreads的数量应该用#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> #include <math.h> #include <semaphore.h> #define finishedNodes 5 #define workersLimitNr 3 int workingThreads = 0; sem_t sem; struct dataBlock{ struct node *root; int listSize; int forIndex; }; struct node { // std linked list node int value; int worker; struct node *next; }; int slots = 0; // only 3 threads are allowed to access the list int availableCheck(){ // check if thread can acces the list if(slots < 3) return 0; else return -1; } pthread_mutex_t mutp = PTHREAD_MUTEX_INITIALIZER; // mutex pthread_cond_t condvar = PTHREAD_COND_INITIALIZER; //condvar void *deleteDoneNodes(struct node *n){ // T H I S I S T H E F U N C struct node *root = n; struct node *it; it = root; do{ if(it->value == 1){ struct node *tmp; printf("DELETING: %d > %d\n", it->value, it->worker ); root = root->next; tmp = it; it = it->next; free(tmp); } else it = it->next; }while(it != NULL); return NULL; } void * worker( void *data ){ struct dataBlock *inData = (struct dataBlock *) data; struct node *root = inData->root; int forIndex = inData ->forIndex; free(data); printf( "* Thread id: %lu forID: %d workerNode: \n",pthread_self(),forIndex); pthread_mutex_lock( &mutp ); if(availableCheck() < 0){ printf( " ^^^ List not available yet... \n" ); pthread_cond_wait( &condvar, &mutp ); } struct node *it = root; printf( " _forID_ %d\n |", forIndex ); do{ if(forIndex == it->worker){ printf("valid for sqrt forIndex %d == it->worker %d\n",forIndex, it->worker ); if(it->value > 2){ while(it->value != 1) it->value = sqrt(it->value); // it->value = it->value - 1; } } it = it->next; }while(it != NULL); pthread_cond_signal( &condvar ); // pthread_mutex_unlock( &mutp ); return NULL; } int main( int argc, char *argv[] ){ if ( argc != 3 ){ printf( "Programm must be called with \n NR of elements and NR of workers! \n " ); exit( 1 ); } int i; struct node *root; struct node *iterator; //prepare list for task int listSize = atoi(argv[1]); int nrWorkers = atoi(argv[2]); root = malloc(sizeof( struct node) ); root->value = rand() % 100; root->worker = 0; iterator = root; for( i=1; i<listSize; i++ ){ iterator->next = malloc(sizeof(struct node)); iterator = iterator->next; iterator->value = rand() % 100; iterator->worker = i % nrWorkers; printf("node #%d worker: %d value: %d\n", i, iterator->worker,iterator->value); } iterator->next = NULL; printf("? List got populated\n"); // init semaphore > keeps max 3 threads working over the list if( sem_init(&sem,0,3) < 0){ perror("semaphore initilization"); exit(0); } // Create all threads to parse the link list int ret; pthread_mutex_init(&mutp,NULL); pthread_t w_thread; pthread_t* w_threads = malloc(nrWorkers * sizeof(w_thread)); for( i=0; i < nrWorkers; i++ ){ struct dataBlock *data = malloc(sizeof(struct dataBlock)); data->root = root; data->listSize = listSize; data->forIndex = i; ret = pthread_create ( &w_threads[i], NULL, worker, (void *) data ); if( ret ) { perror("Thread creation fail"); exit(2); } } deleteDoneNodes( root ); // printf( ">>>> %d\n", root->value ); for ( i = 0; i < nrWorkers; i++ ){ pthread_join(w_threads[i],NULL); } // for ( i = 0; i < nrWorkers; i++){ // free(w_threads); // } iterator = root; for ( i = 0; i < listSize; i++){ printf("val: %d worker: %d _ ", iterator->value, iterator->worker); iterator = iterator->next; } free(root); free(iterator); return 0; } 删除每个节点,但它没有做任何事情......

代码:

{{1}}

PS:它编译/工作错误/无警告 - 也用valgrind测试。

1 个答案:

答案 0 :(得分:1)

这是一个替代版本

void *deleteDoneNodes(struct node *n){
    struct node *root = n;
    struct node *it = root;
    struct node *prev = NULL;
    do{
        if(it->value == 1){
            struct node *next = it->next;
            if (prev != NULL) {
                prev->next = next;
            }
            if (it == root) {
                root = next;
            }
            free(it);
            it = next;
        }
        else {
            prev = it;
            it = it->next;
        }
    }while(it !=  NULL);

    return root;
}

主要变化是:

  • 处理从列表中间删除项目的操作。上一项需要更改其next指针。没有它,它将继续指向释放的记忆。
  • 更新root的逻辑。只有在我们免费root
  • 时才需要这样做
  • root中传达可能的变化。如果我们从列表中删除root(aka head)项,则需要将其传递给调用者。我通过返回root而不是NULL
  • 的(可能更新的)值来完成此操作