在 C 函数中修改指针时出现问题



嗨,我正在尝试在 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)

有人可以帮助我了解我在这里错过了什么吗?

代码中的指针一团糟

请尝试以下操作。只考虑到我没有将程序拆分为模块并使用显式指定的字符串。您可以删除它或取消注释 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 ]

您正在修改 beginInsertSLNroot的本地副本。它不会更改mainroot的值。

这应该有效:

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);
   }
}

让我们将您的代码简化为我发现的第一个错误:

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)).

最新更新