修改C函数内的指针时出现问题

时间:2014-12-08 17:58:58

标签: c list pointers

您好我正在尝试在C中实现一个喜欢的llist操作。我的方法是在头文件C文件中实现所有操作,并将其包含在主文件中以管理链接列表。

这是头文件linkedlist.h,包含操作实现

//Here is my code for the node structure:

struct node {
  struct node * next;
  char cinfo;
};


//Here is a method to do a simple insertion in the begining of the list

 void beginInsertSL(char val, struct node ** root){    
  struct node *p = malloc(sizeof(struct node*));
  p->cinfo = val;

  if(*root == NULL){
    p->next = NULL;
  } else {
    p->next = *root;
  }

  *root = p;
};

//Here is a method to do many insertions

void beginInsertSLN(char *ch, struct node **root){
  root  = malloc(sizeof(struct node**));

  int size, i;

  size = strlen(ch);
  i = 0;

  if(size > 0){
    while(i < size){
      beginInsertSL(ch[i], root);
      printSL(*root);
      i++;
    }
  } else *root = NULL;
}

//And finally a method to print a list, to be able to see 

void printSL(struct node *root){
   struct node *p;

  if(root == NULL) printf("[ ]\n");
  else {
    p = root;

    printf("[ %c", p->cinfo);

    while(p->next != NULL) {p = p->next; printf("->%c", p->cinfo);}

    printf(" ]\n");
  }
}

这是使用这些方法的主要功能

#include "linkedlist.h"
#include <stdio.h>

int main(int argc, char *argv[]){

   // declaring the root of my linkedlist
   struct node **root = NULL;

   if(argc > 0){
     // inserting char in the linked list
     beginInsertSLN(argv[1], root);

     // print the linked list to see the result
     printSL(*root);
   }
}

执行此代码时,我得到以下结果:

./lltest stackoverflow
[ s ]
[ t->s ]
[ a->t->s ]
[ c->a->t->s ]
[ k->c->a->t->s ]
[ o->k->c->a->t->s ]
[ v->o->k->c->a->t->s ]
[ e->v->o->k->c->a->t->s ]
[ r->e->v->o->k->c->a->t->s ]
[ f->r->e->v->o->k->c->a->t->s ]
[ l->f->r->e->v->o->k->c->a->t->s ]
[ o->l->f->r->e->v->o->k->c->a->t->s ]
[ w->o->l->f->r->e->v->o->k->c->a->t->s ]
Erreur de segmentation (core dumped)

有人可以帮我理解我在这里缺少的东西吗?

3 个答案:

答案 0 :(得分:1)

让我们将您的代码减少到我找到的第一个错误:

void beginInsertSLN(char *ch, struct node **root){
    root = malloc(sizeof(struct node**));
}

int main(int argc, char *argv[]){
   struct node **root = NULL;
   beginInsertSLN("stackoverflow", root);

   assert(root == NULL);
}

请注意,根据此代码,root将保持等于NULL。这当然不是你想要的。

你可能想要这样的东西:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct node {
    struct node * next;
    char cinfo;
};

void beginInsertSL(char val, struct node **root){
    struct node *p = malloc(sizeof *p);
    p->cinfo = val;
    p->next = *root;

    *root = p;
}

void beginInsertSLN(char *str, struct node **root){
    int i;
    for (int i=0; i<strlen(str); ++i)
        beginInsertSL(str[i], root);
}

void printSL(struct node *root){
    if(root == NULL) {
        printf("[ ]\n");
        return;
    }

    struct node *p = root;
    printf("[ %c", p->cinfo);
    while(p->next != NULL) {
        p = p->next;
        printf("->%c", p->cinfo);
    }
    printf(" ]\n");
}

int main(int argc, char *argv[]){
    struct node *root = NULL;

    beginInsertSLN("stackoverflow", &root);
    printSL(root);
}

此外,值得明确地称之为另一个错误:

struct node *p = malloc(sizeof(struct node*));

你正在分配错误的空间!它应该是malloc(sizeof(struct node))

答案 1 :(得分:1)

您正在root修改beginInsertSLN的本地副本。它不会更改rootmain的值。

这应该有效:

int main(int argc, char *argv[]){

   // declaring the root of my linkedlist
   struct node *root = NULL;
           //  ^^ Use node *root, not node **root

   if(argc > 0){
     // inserting char in the linked list
     beginInsertSLN(argv[1], &root);
                          // ^^ Pass the address of root, not root.

     // print the linked list to see the result
     printSL(root);
   }
}

答案 2 :(得分:1)

你的代码中有一些乱七八糟的指针

尝试以下方法。只考虑到我没有将程序拆分为模块并使用明确指定的字符串。您可以将其删除或取消注释main中的字符串定义以测试程序。

#include <stdio.h>
#include <stdlib.h>

//Here is my code for the node structure:
struct node 
{
    struct node *next;
    char cinfo;
};


//Here is a method to do a simple insertion in the begining of the list

void beginInsertSL( struct node **root, char c )
{    
    struct node *p = malloc( sizeof( struct node ) );
    p->cinfo = c;
    p->next = *root;

    *root = p;
}

void printSL( struct node *root );

//Here is a method to do many insertions

void beginInsertSLN( struct node **root, const char *s  )
{
    while ( *s )
    {
        beginInsertSL( root, *s++ );
        printSL( *root );
    }
}

//Here is a method to print a list, to be able to see 

void printSL( struct node *root )
{
    if ( root == NULL ) 
    {
        printf( "[ ]\n" );
        return;
    }

    printf( "[ %c", root->cinfo );

    while( ( root = root->next ) != NULL ) 
    {
        printf( "->%c", root->cinfo );
    }

    printf(" ]\n");
}

//And finally a method to clear the list 

void clear( struct node **root )
{
    while ( *root )
    {
        struct node *tmp = *root;
        *root = ( *root )->next;
        free( tmp );
    }
}    

int main( int argc, char * argv[] )
{
    struct node *root = NULL;

    if ( argc > 1 ) beginInsertSLN( &root, argv[1] );

//    char *s = "stackoverflow";
//    beginInsertSLN( &root, s );

    printSL( root );

    clear( &root );

    return 0;
}

输出

[ s ]
[ t->s ]
[ a->t->s ]
[ c->a->t->s ]
[ k->c->a->t->s ]
[ o->k->c->a->t->s ]
[ v->o->k->c->a->t->s ]
[ e->v->o->k->c->a->t->s ]
[ r->e->v->o->k->c->a->t->s ]
[ f->r->e->v->o->k->c->a->t->s ]
[ l->f->r->e->v->o->k->c->a->t->s ]
[ o->l->f->r->e->v->o->k->c->a->t->s ]
[ w->o->l->f->r->e->v->o->k->c->a->t->s ]
[ w->o->l->f->r->e->v->o->k->c->a->t->s ]