我不明白为什么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;
}
答案 0 :(得分:0)
&*accountslist[1]
相当于accountslist[1]
,而&*unameslist[0]
相当于unameslist[0]
,因此您可以将该行重写为:
if( accountslist[1] == unameslist[0] ) printf("WHY??\n" );
问题是accountslist
和unameslist
都是指向您的列表的指针,即它们的类型为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;
}