C 如何使两个双指针相等

C 如何使两个双指针相等,c,global,local,dynamic-arrays,C,Global,Local,Dynamic Arrays,好的,大家好 我让这个工作: char **list = NULL; // global int number_of_strings = 0; // global void empty_list_of_strings(void); void add_string_to_list(char *string); void print_list_of_strings(void); int main(int argc, char **argv) { add_string_to_li

好的,大家好

我让这个工作:

char **list = NULL;   // global
int number_of_strings = 0;   // global

void empty_list_of_strings(void);
void add_string_to_list(char *string);
void print_list_of_strings(void);

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

    add_string_to_list("Warrior");
    add_string_to_list("Magician");
    add_string_to_list("Pirate");

    print_list_of_strings();

    empty_list_of_strings();

    return 0;
}

void empty_list_of_strings(void) {
    int k=0;

    if(list != NULL) {
        for(k=0; k number_of_strings; k++) { // less than
            if(list[k] != NULL) {
                free(list[k]);
            list[k] = NULL;
        }
    }

    free(list);
    list = NULL;
    number_of_strings = 0;
    }
}

void add_string_to_list(char *string) {
    if(list != NULL) {
        list=realloc(list, (number_of_strings + 2) * sizeof(char*));
        list[number_of_strings]=malloc( (strlen(string) + 1) * sizeof(char));
        strcpy(list[number_of_strings], string);
        number_of_strings++;
        list[number_of_strings]=NULL;
    } else {
        list = malloc( (number_of_strings +2) *sizeof(char *));
        list[number_of_strings]=malloc( (strlen(string) + 1) * sizeof(char) );
        strcpy(list[number_of_strings], string);
        number_of_strings++;
        list[number_of_strings]=NULL;
    }
}

void print_list_of_strings(void) {
    int k=0;

    if(list != NULL) {
        for(;k number_of_strings;k++) { // less than
            if(list[k] != NULL) {
                printf("list[%d] = %s\n", k, list[k]);
            }
        }
    }
}
现在我想让函数更通用一些,所以我尝试更改add_string_to_list函数,使其看起来像这样:

void add_string_to_list(char** test, char *string);
void add_string_to_list(char ***test, char *string) {
   if (*test != NULL) {
      *test=realloc( ... );
      ...
   } else {
      *test=malloc( ... );
      ...
   }
}
大体上,我改变了这一点:

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

    char **local = list;   // is this possible ???

    add_string_to_list(local, "Warrior");
    add_string_to_list(local, "Magician");
    add_string_to_list(local, "Pirate");

    list = local;     // is this possible ???

    print_list_of_strings();

    empty_list_of_strings();

    return 0;
}
最后,我将add_string_to_list函数更改为:

void add_string_to_list(char **test, char *string) {
    if(test != NULL) {
        test=realloc(test, (number_of_strings + 2) * sizeof(char*));
        test[number_of_strings]=malloc( (strlen(string) + 1) * sizeof(char));
        strcpy(test[number_of_strings], string);
        number_of_strings++;
        test[number_of_strings]=NULL;
    } else {
        test = malloc( (number_of_strings +2) *sizeof(char *));
        test[number_of_strings]=malloc( (strlen(string) + 1) * sizeof(char) );
        strcpy(test[number_of_strings], string);
        number_of_strings++;
        test[number_of_strings]=NULL;
    }
}

现在我根本没有得到任何输出。就像add_to_string函数没有得到正确的指针一样?我是否以正确的方式向函数发送指针?可以这样做吗?

这样,您就不再需要更改您拥有的实际内容,即
中的
本地
。您只需收到一份副本,并对其进行更改

要实现您想要的功能,您必须将
本地
的地址传递到
添加字符串到列表
,并接收
字符***测试
,而不是
字符**测试
;然后在函数中出现的
测试
后面添加
*
s,必要时用括号括起来
()

连同3个适当的函数调用
add_string_到_列表(&local,…)
main
中,将函数定义更改为以下内容将执行以下操作:

void add_string_to_list( char ***test, char *string ) {
    if ( *test != NULL ) {
        *test = realloc( *test, ( number_of_strings + 2 ) * sizeof( char* ) );
        (*test)[number_of_strings] = malloc( ( strlen( string ) + 1 ) * sizeof(char) );
        strcpy( (*test)[number_of_strings], string );
        number_of_strings++;
        (*test)[number_of_strings] = NULL;
    }
    else {
        *test = malloc( ( number_of_strings + 2 ) *sizeof( char * ) );
        (*test)[number_of_strings] = malloc( ( strlen( string ) + 1 ) * sizeof(char) );
        strcpy( (*test)[number_of_strings], string );
        number_of_strings++;
        (*test)[number_of_strings] = NULL;
    }
}

有一件事:您还缺少了一些
问题是
将字符串添加到列表
函数只是修改了它的
测试的本地副本。如果要将列表表示为
char**
,则
add_string_to_list
函数必须这样编写:

void add_string_to_list(char** test, char *string);
void add_string_to_list(char ***test, char *string) {
   if (*test != NULL) {
      *test=realloc( ... );
      ...
   } else {
      *test=malloc( ... );
      ...
   }
}
许多程序员更喜欢通过声明一个结构来表示列表来避免这种指针混淆:

typedef struct {
   char **strings;
   int numStrings;
} StringList;
然后,您可以使用以下命令初始化列表:

StringList list = { .strings=NULL, .numStrings=0 };
然后,
将字符串添加到列表中
函数将如下所示:

void add_string_to_list(StringList *list, char *string) {
   if (list->strings != NULL) {
      list->strings = realloc( ... );
      ...
      list->numStrings++;
   } else {
      list->strings = malloc( ... );
      ...
      list->numStrings++;
   }
}
然而,我不喜欢在编写代码时重复我自己,我还认为为每个新列表项执行
realloc()
效率低得离谱,因此我会:

typedef struct {
   char **strings;
   int  numStrings;
   int  capacity;
} StringList;

void init_string_list(StringList *list, int capacity) {
   list->strings = (char **) malloc(capacity * sizeof(char *));
   list->capacity = capacity;
   list->numStrings = 0;
}

void resize_string_list(StringList *list, int increment) {
   list->capacity += increment;
   list->strings = (char **) realloc(list->strings, 
                                     (list->capacity * sizeof(char *)));
}

void add_string_to_list(StringList *list, char *string) {
   if ((list->capacity - list->numStrings) < 1)
      resize_string_list(list, SOME_REASONABLE_INCREMENT_SIZE);

   list->strings[list->numStrings++] = strdup(string);
}

...


int main(int argc, char **argv) {
   StringList list = {0};

   init_string_list(&list, SOME_REASONABLE_STARTING_CAPACITY);

   add_string_to_list(&list, "foo");
   add_string_to_list(&list, "bar");
   add_string_to_list(&list, "baz");

   ...
}
typedef结构{
字符**字符串;
整数字符串;
国际能力;
}字符串列表;
无效初始字符串列表(字符串列表*列表,整数容量){
列表->字符串=(字符**)malloc(容量*sizeof(字符*);
列表->容量=容量;
列表->数值字符串=0;
}
无效调整大小字符串列表(字符串列表*列表,整数增量){
列表->容量+=增量;
列表->字符串=(字符**)realloc(列表->字符串,
(列表->容量*大小(字符*);
}
void将字符串添加到列表(字符串列表*列表,字符*字符串){
如果((列表->容量-列表->数值字符串)<1)
调整字符串列表大小(列表,一些合理的增量大小);
列表->字符串[列表->numStrings++]=strdup(字符串);
}
...
int main(int argc,字符**argv){
字符串列表={0};
初始化字符串列表(&list,一些合理的启动容量);
将字符串添加到列表(&list,“foo”);
将字符串添加到列表(&list,“bar”);
将字符串添加到列表(&list,“baz”);
...
}

当然,这只是举个例子。仍然有许多方法可以改进此代码。但是我想你会同意,
StringList*list
(或类似的东西)比
char***list

好看得多,因此更容易理解(和维护)为什么数组中的其他条目都是空的?另外,
add\u string\u to_list
只需要
realloc
大小写,因为带有
NULL
指针的
realloc
相当于
malloc
。此外,您还陷入了
realloc
陷阱,在指针的唯一副本上分配返回值。如果失败并返回
NULL
,原始内存将保持分配状态,但您将不再知道它在哪里。你好,帕特,谢谢您的评论。我知道这段代码在检查realloc和malloc的返回值时有不足之处。我只是被这样一个事实难住了:我无法将**char指针发送到我的函数来更改函数中的值。我需要一个以NULL结尾的字符串列表。这是用于amiga计算机上的系统功能。啊,是的,您只是将最后一个条目设置为
NULL
,但不会再次增加
字符串数。我错了,你好,索波辛!谢谢你对这个问题的澄清。我已经为此挣扎了好几天了,但还是没能让它像我想的那样工作。有了你的解决方案,它就完美地工作了。@user3439105我很高兴我帮助了我的朋友。你用我的名字跟我打招呼,好像你从别的地方认识我一样;是这样,还是只有我一个人?你好!不,我在别的地方不认识你,这只是我打招呼的方式。:)你好,迈克!我非常感谢您的输入,我相信我将在未来的项目中使用它,但在这种情况下,我不确定我是否可以使用除char**以外的任何其他类型,因为我将把这个char**列表插入到amiga计算机上的一个系统函数中,该函数期望具有char**。BR JJN不担心。使用你喜欢的任何解决方案。不过,我应该指出,在我的解决方案中,您仍然将列表表示为
char**
。为了方便起见,它只是包装在一个结构中。您可以轻松地将
list->strings
传递给需要
char**
的系统函数,如
某些系统函数(list->strings)