首页 > 解决方案 > C 使用指向指针的指针在动态增加的数组中传递值

问题描述

我正在编写一个 C 程序,在该程序中我必须对未知数量的结果进行搜索,将结果放在某种结构中,然后从程序中的各个位置访问该结构。

在我看来,这就像 C 句柄对象(指向指针的指针)可以很好地工作的地方。我给出了我希望程序访问句柄的结构,一个不会改变的指针,这样程序的任何部分都可以得到它。我在某种数组上有一个稳定的句柄点,它将在程序期间创建,并且其地址会随着它所持有的数据的增长或缩小而改变。

C 有你需要做的一切:可以指向其他指针的指针;为扩展对象动态分配内存。但是:要在 C 语言中执行此操作,您必须知道如何将 * ** & 与括号 ()[] 和 -> 以及句点 (.) 结合使用。例如,您必须知道 *(place+j) 与 place[j] 相同,(*place)[j] 和 *(*place+j) 也是如此,以及 place->thing 的确切含义, place.thing 和 (*place)->thing 不同。等等。因此,尽管我已经编写了 30 年的 C 程序,但我仍然花了几个小时才把它做好。

这是工作解决方案的代码。我有一个包含两个句柄的结构process_book_inf,指向我要访问的数据。我希望这些句柄之一访问整数数组search_els_found,它可能是任何长度。我希望另一个访问指向bounds_obj结构的指针数组,其中可能还有任意数量的此类结构。两个函数testInttestPtr创建两个这样的数组,随着它们的增长创建指向数组的新指针,然后将新数组的地址放入主process_book结构中。

这是我的问题:我的代码有效,但我不确定它是否像它可能的那样优雅、简单和透明。有很多人比我更精通 C。有人有想法么?(附带说明:这个例子展示了 C 的强大功能)。

#include <stdio.h>
#include <stdlib.h>

struct process_book_inf {
    void *search_els_found;
    void **search_texts_found;
};
typedef struct process_book_inf *process_book_ptr;

struct bounds_obj {
    int start_el;
    int start_off;
};
typedef struct bounds_obj *bounds_ptr;

void testInt(void **resultArray);
void testPtr(void **resultArray);

int main(int argc, const char * argv[]) {
    process_book_ptr testMemory=malloc(sizeof(struct process_book_inf));
    testInt((void **) &testMemory->search_els_found);
    for (int c=0; c<5; c++) {
        printf("retrieved %d\r", *((int *) (testMemory->search_els_found)+c));
    }
    testPtr((void **) &testMemory->search_texts_found);
    for (int c=0; c<5; c++) {
        bounds_ptr *dest= (bounds_ptr *) (testMemory->search_texts_found)+c;
        printf("retrieved structure values %d %d\r", (*dest)->start_el, (*dest)->start_off);
    }
    return 0;
}

void testInt(void **testarray) {
    int *place=(int *) malloc(sizeof(int));
    int **already=(int **) testarray;
    for (int c=0; c<5; c++) {
        if (c>0) {
            free(place);
            place=(int *) malloc((c+1) *sizeof(int));
            for (int j=0; j<c; j++){
                place[j]=(*already)[j];
 //             *(place+j)=*(*already+j);
            }
        }
         *(place+c)=c*100+c;
         printf("set %d\r", *(place+c));
        *already=place;
    }
}

//in this version, simplify as far as I can
//replace *(place+j) by place[j]; remove all redundant casts
void testPtr(void **textarray) {
    bounds_ptr *place= malloc(sizeof(bounds_ptr));
    bounds_ptr **already=(bounds_ptr **) textarray;
    for (int c=0; c<5; c++) {
        if (c>0) {
            free(place);
            place= malloc(sizeof(bounds_ptr)*(c+1));
            for (int j=0; j<c; j++){
                place[j]= (*already)[j];
             }
        }
        struct bounds_obj *dest= malloc(sizeof(struct bounds_obj));
        dest->start_el=(c*100)+1;
        dest->start_off=(c*100)+2;
        place[c]=dest;
        printf("set structure values %d %d\r", place[c]->start_el, place[c]->start_off);
        *already= place;
    }
}

结果是:

set 0
set 101
set 202
set 303
set 404
retrieved 0
retrieved 101
retrieved 202
retrieved 303
retrieved 404
set structure values 1 2
set structure values 101 102
set structure values 201 202
set structure values 301 302
set structure values 401 402
retrieved structure values 1 2
retrieved structure values 101 102
retrieved structure values 201 202
retrieved structure values 301 302
retrieved structure values 401 402
Program ended with exit code: 0

标签: carrayspointersdynamichandle

解决方案


推荐阅读