指针问题,数组第二个位置与另一个数组中的第一个位置相同

时间:2014-10-18 23:00:52

标签: c arrays pointers malloc realloc

我不明白为什么if语句:& * accountslist [1] ==& * unameslist [0]为真。这里发生了什么?我的realloc有问题吗?此外,当我使accountlist [1] = NULL时,似乎unameslist [0]也被设置为null。这让我觉得由于某种原因他们最终指向同一个位置。

int loadInfo( char*** accountslist, 
          char*** unameslist, 
          char*** passlist )
{
    FILE* account_file = fopen( ACCOUNTS_LOCATION, "r" );
    FILE* uname_file = fopen( UNAMES_LOCATION, "r" );
    FILE* pass_file = fopen( PASSWORDS_LOCATION, "r" );

    char* nextAccount;
    char* nextUname;
    char* nextPass;

    fileWithNum( account_file, &nextAccount );
    fileWithNum( uname_file, &nextUname );
    fileWithNum( pass_file, &nextPass );

    *accountslist = (char**) malloc( sizeof(char*) );
    *unameslist = (char**) malloc( sizeof(char*) );
    *passlist = (char**) malloc( sizeof(char*) );

    *accountslist[0] = nextAccount;
    *unameslist[0] = nextUname;
    *passlist[0] = nextPass;

    int num_accounts = 1;

    while( nextAccount != NULL && nextUname != NULL &&
           nextPass != NULL )
    {
        *accountslist = (char**)realloc( *accountslist, 
                                 (num_accounts + 1) * sizeof(char*));
        *unameslist = (char**)realloc( *unameslist,
                               (num_accounts + 1) * sizeof(char*));
        *passlist = (char**)realloc( *passlist,
                             (num_accounts + 1) * sizeof(char*));
        fileWithNum( account_file, &nextAccount );
        fileWithNum( uname_file, &nextUname );
        fileWithNum( pass_file, &nextPass );
        printf( "%s\n" , *unameslist[0] );
        *accountslist[1] = NULL;
        if( &*accountslist[1] == &*unameslist[0] ) printf("WHY??\n" );
        printf( "%s, %s, %s\n" , *accountslist[0], *unameslist[0], *passlist[0]);

        *accountslist[num_accounts] = nextAccount;
        *unameslist[num_accounts] = nextUname;
        *passlist[num_accounts] = nextPass;

        printf( "%s, %s, %s\n" , *accountslist[num_accounts],
            *unameslist[num_accounts], *passlist[num_accounts]);
        num_accounts++;
    }

    fclose( account_file );
    fclose( uname_file );
    fclose( pass_file );

    return num_accounts;
}

2 个答案:

答案 0 :(得分:0)

&*accountslist[1]相当于accountslist[1],而&*unameslist[0]相当于unameslist[0],因此您可以将该行重写为:

if( accountslist[1] == unameslist[0] ) printf("WHY??\n" );

问题是accountslistunameslist都是指向您的列表的指针,即它们的类型为char ***。它们本身不是数组,因此unameslist[0]等同于*unameslist,它是实际unameslist数组的地址,accountslist[1]实际上是超出范围的。由于这会使你陷入不确定的行为领域,你不能指望事情表现得明智。可能发生的事情是,在调用loadInfo()之前,您在unameslist指向的位置之前声明了accountslist指向的内容,以便accountslist[1]实际评估为与*unameslist相同的地址。这个简短的程序演示了如何实现这一点:

#include <stdio.h>

void myfunc(char *** pp1, char *** pp2)
{
    /*  WARNING - undefined behavior ahead  */

    printf("pp1[1] is %p, pp2[0] is %p\n", (void *) pp1[1], (void *) pp2[0]);
}

int main(void)
{
    char ** p1 = (char **) 0xCC;
    char ** p2 = (char **) 0xFF;
    printf("p1 is %p, p2 is %p\n", (void *) p1, (void *) p2);
    printf("&p1 is %p, &p2 is %p\n", (void *) &p1, (void *) &p2);
    myfunc(&p2, &p1);
    return 0;
}

,至少在我跑的时候输出了:

paul@thoth:~/src/sandbox$ ./pdemo
p1 is 0xcc, p2 is 0xff
&p1 is 0x7fff8d138818, &p2 is 0x7fff8d138810
pp1[1] is 0xcc, pp2[0] is 0xcc
paul@thoth:~/src/sandbox$ 

您可以看到pp1[1]pp2[0]由于滥用指针而比较相等。如果您将pp1[1]更改为&*pp1[1],同样更改为pp2[0],则您会看到您获得完全相同的结果,因为它们相同。

你的意思可能是:

if( (*accountslist)[1] == (*unameslist)[0] ) printf("WHY??\n" );

请注意,[]的绑定比*更紧密,因此*accountslist[1]相当于*(accountslist[1]),当您真正想要的是先尊重accountslist时,所以你需要(*accountslist)[1]

这里简短的回答是,你有太多的间接性,你会让自己感到困惑,并且极度滥用你的指针。结果,几乎没有一个代码正在做你认为它正在做的事情。您应该使用一些临时变量来简化并使自己更容易,例如:

char ** local_accounts_list = malloc(sizeof *local_accounts_list);

然后仅在最后用以下内容更新您的参数:

*accountslist = local_accounts_list;

您还应该检查来自malloc()和朋友,fopen()以及可能失败的任何其他功能的返回,这是您永远不会做的。如果你没有检查错误,当事情不起作用时,你会感到惊讶。

答案 1 :(得分:0)

如果有人有兴趣,这里是fileWithNum

int fileWithNum( FILE* fptr, char** word )
{
  //finished fixing
  int size;
  char* temp = NULL;
  fscanf( fptr, "%d", &size );
  if( size == -1) 
  {
    return 0;
  }
  int character = 0;
  temp = (char*) malloc( (size + 1) * sizeof(char));
  int current;
  for( current = 0; current < size; current++ )
  {
      if( fscanf( fptr, "%d", &character ) != 1 )
      {
          printf( "fscanf error\n" );
      }
      //printf( "%c\n" , character );
      //printf( "%d\n" , current );
      temp[current] = character;
  }
  temp[size] = 0; //end of string char
  *word = temp;
  printf( "End of filewithnum\n" );
  return 0;
}