【问题标题】:Pointer value changing指针值变化
【发布时间】:2014-03-13 18:12:50
【问题描述】:

输入文件:

JOHN 9999999999
MEENA 9888888888
RIA 8718218218
SONIA 7777777777
FINCH 1234567890
  • 我想通过将文件的内容附加到列表中来创建一个循环链表。我创建了一个带有“NO VALUE”条目的哨兵。

  • 当我在 gdb 中测试我的代码时,uploadAddresses() 中 while 循环结束时的 p->next->name 显示 Finch。这怎么可能?p 值保持不变,只有 temp 值在每次迭代后发生变化。

    #include<stdio.h>    
    #include<stdlib.h>    
    #include<string.h>    
    #define MAXPHONENO 100
    
    //Variables declaration 
    struct Contact {
      char *name;
      char *mobileno;
      struct Contact *next;
    };
    typedef struct Contact Contact;    
    typedef Contact* PHBOOK;
    
    //Function declaration
    PHBOOK createAddressBook();
    PHBOOK uploadAddresses(PHBOOK pb,char *name);
    
    //Implementation
    PHBOOK createAddressBook(){    
      PHBOOK pb = (PHBOOK)malloc(sizeof(Contact));   
      pb->name = "NO ENTRY";    
      pb->mobileno = "NO ENTRY";    
      pb->next = pb;    
      return pb;    
    }
    
    
    PHBOOK uploadAddresses(PHBOOK p,char *fname){
      PHBOOK temp = p;
      char mob[20],name[20];
      FILE *fp = fopen(fname,"r");
      while(fscanf(fp,"%s %s",name,mob)!=EOF){
        temp->next = (PHBOOK)malloc(sizeof(Contact));    
        temp = temp->next;    
        temp->name = name;    
        temp->mobileno = mob;    
        printf("%s %s\n",name,mob);    
      }    
      temp->next = p;    
      return p;    
    }   
    
    int main(){    
      PHBOOK pb = createAddressBook();    
      pb = uploadAddresses(pb,"/home/user/names_mobile");    
      return 0;
    }
    

【问题讨论】:

  • 函数createAddressBook的代码在哪里?
  • 我已经发布了 createAddressBook() 的代码
  • 如果你想要一个循环链表,为什么你只指向下一项而不是前一项?此外,为了定义列表的最后一个元素,指向下一个元素的指针被定义为null,而不是自身。

标签: c pointers semantics


【解决方案1】:

变化:

temp->name = name;
temp->mobileno = mob;    

收件人:

temp->name = malloc(strlen(name)+1);
temp->mobileno = malloc(strlen(mob)+1);
strcpy(temp->name,name);
strcpy(temp->mobileno,mob);

【讨论】:

  • 正确,您已将namemobileno 定义为指向字符的指针。奇怪的是您没有收到一些分段错误。
【解决方案2】:
temp->name = name;

您只将指针分配给temp-&gt;name

这个指针指向一个局部变量。

编辑:

在您的情况下, fscanf 使用 char name[20] 来包含输入名称,它的上下文在每个循环中都发生了变化。在while循环结束时它会是“Finch”。

我们知道“temp->name”指向包含“Finch”的“char name[20]”,这就是你看到它的原因。

【讨论】:

  • 您可能想添加一个解释,说明为什么存储对局部变量的引用不是一个好主意。
【解决方案3】:

malloc 一些内存用于

char *name;
char *mobileno;

这也将解决您的问题。

PHBOOK uploadAddresses(PHBOOK p,char *fname){

PHBOOK temp = p;
char mob[20],name[20];

FILE *fp = fopen(fname,"r");


  while(fscanf(fp,"%s %s",name,mob)!=EOF)
  {
    temp->next = (PHBOOK)malloc(sizeof(Contact));  
    temp = temp->next; 
    temp->name = (char*)malloc(sizeof(char) * MAX_NAME) ;    
    temp->mobileno = (char*)malloc(sizeof(char) * MAX_PHNO) ;  

   strcpy(temp->name,name);
    strcpy(temp->mobileno,mob);

  }    
    temp->next = p;    
    return p;    

}

【讨论】:

    【解决方案4】:

    改进的代码:

    注意 修饰符,它为字符串动态分配空间。也必须关闭文件,否则会发生资源泄漏。

        PHBOOK uploadAddresses(PHBOOK p,char *fname){
          PHBOOK temp = p;
          char *mob,*name;
          FILE *fp = fopen(fname,"r");
    
          if (!fp)
            return temp;
    
          while (fscanf(fp,"%ms %ms",&name,&mob)!=EOF) {  
            temp->next = malloc(sizeof(Contact));       
            temp = temp->next;
            temp->name = name;    
            temp->mobileno = mob;    
            printf("%s %s\n",name,mob);    
          }
    
          fclose(fp);
          temp->next = p;    
          return p;  
        }   
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-22
      • 2023-03-28
      • 2014-03-01
      • 1970-01-01
      • 2013-04-01
      • 1970-01-01
      • 2013-08-24
      相关资源
      最近更新 更多