如何在C中的结构中的双指针中使用malloc()

how to use malloc () in Double Pointer in Structure in C

我有结构:

    typedef struct accont
{
    char **tel;//list of tel
    char **email;//list of emails
}acc;

typedef struct _strcol
{
    int count;      //total of accounts
    acc **list;
} strcol ;

我用指针访问结构:

strcol index;
contato *p;
p = (index.list + index.count);

问题,我如何在此函数中使用 malloc()?

我试试:

(*p)->tel = (char **) malloc(i * sizeof (char*))

p.tel = (char **) malloc(i * sizeof (char*))

&(*p)->tel = (char **) malloc(i * sizeof (char*))

然后就像我做的第二个 malloc 来保存数据 email 或 tel

我的第一个post,请见谅

所以这个:

(*p)->tel = (char **) malloc(i * sizeof (char*))

分配 space 以存储 i 指向 char 的指针 - 因此您可以拥有 i 电话号码字符串。但是您实际上还没有分配任何 space 来存储这些电话号码字符串本身。为此,您需要(第一个电话号码):

(*p)->tel[0] = malloc(j);

如果对 malloc() 的调用成功,您现在可以将长度为 j-1 的以 nul 结尾的字符串存储在 (*p)->tel[0] 指向的 space 中。然后,您可以对 (*p)->tel(*p)->tel[i-1].

中的其他指针执行相同的操作

使用 malloc() 很简单,如果代码如下:

some_type *p;
p = malloc(number_of_elements * sizeof *p);
if (p == NULL) Handle_OutOfMemory();

因此 p.tel

// p.tel = (char **) malloc(i * sizeof (char*));
p.tel = malloc(i * sizeof *(p.tel));
if (p.tel == NULL) exit(EXIT_FAILURE);

如果我对案例的理解是正确的,那么 stack 实施将最适合这种情况。您可以使用(gcc 的)标准 stack 库头或创建适合您自己需要的堆栈实现。

示例可能类似于下面的代码,但您最好观看 Jerry Cain 关于堆栈过程的视频(您可以在 youtube 上找到这些视频: Stanford - Programming Paradigms 视频。Stack session 应该在视频编号 6 到 8 之间)。 link from here

注意:小心!杀死堆栈元素(通过 StackPop)不会杀死 strdup 创建的 char 字符串。您需要单独释放它们。这些在视频中有解释,但我不完全记得是如何解释的(同样,您会在这些视频中为您的案例找到一些有价值的信息)。

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

typedef struct {
    char *tel;
    char *email;
} account;

typedef struct {
    int *ptrElement; // starting address of the stack
    int sizeAllocat; // total size allocated
    int sizeCurrent; // current size
    int sizeElement; // byte length of the stack element
} Stack;

// create a new stack pointer
void StackNew (Stack *s, int sizeElement) {
    assert (s->ptrElement > 0);
    s->sizeElement = sizeElement;
    s->sizeCurrent = 0;
    s->sizeAllocat = 4;
    s->ptrElement = malloc (4 * sizeElement);
    assert (s->ptrElement != NULL);
}

// kills a stack pointer
void StackDispose (Stack *s) {
    free (s->ptrElement);
}

// expands stack space
static void StackGrow (Stack *s) {
    s->sizeAllocat *= 2;
    s->ptrElement = realloc (s->ptrElement, s->sizeAllocat * s->sizeElement);
}

// insert new stack pointer (of type account for example)
void StackPush (Stack *s, void *ptrElement) {
    if (s->sizeCurrent == s->sizeAllocat) {
        StackGrow (s);
    }
    void *target = (char *) s->ptrElement + s->sizeCurrent * s->sizeElement;
    memcpy (target, ptrElement, s->sizeElement);
    s->sizeCurrent++;
}

// pops (deletes) an element from stack
void StackPop (Stack *s, void *ptrElement) {
    void *source = (char *) s->ptrElement +
                   (s->sizeCurrent - 1) * s->sizeElement;
    memcpy (ptrElement, source, s->sizeElement);
    s->sizeCurrent--;
}

// relocate stack element
void StackRotate (void *first, void *middle, void *after) {
    int foreSize = (char *) middle - (char *) first;
    int backSize = (char *) after - (char *) middle;
    char tmp [foreSize];
    memcpy (tmp, first, foreSize);
    memmove (first, middle, backSize);
    memcpy ((char *) after - foreSize, tmp, foreSize);
}

int main () {
    Stack s;
    account *acc;
    StackNew (&s, sizeof (acc));

    // your code here
    // example
    // acc->tel = strdup("some number");
    // acc->email = strdup("some text");
    // StackPush(&s, &acc);
    ...
    // StackPop(&s, &acc);
    ...
    ...

    StackDispose (&s);
    return 0;
}

我假设 'p' 是 acc *p; (我不知道 'contato' 是什么)。 无论如何......重点是展示如何分配内存& tel/email数据stored/accessed......还复制了电话#/电子邮件ID只是为了演示...... 关于从 malloc 中转换 void 指针 returns,我看到了参数 for/against ... 我转换了(malloc 是我转换的唯一情况)。

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

typedef struct accont
{
        char **tel;    //list of tel
        char **email;  //list of emails
}acc;

typedef struct _strcol
{
        int count;      //total of accounts
        acc **list;
}strcol;

int main()
{
        int iNumAccounts = 5;   // Assume there are 5 Accounts.
        int iNumTels = 2;       // Each Account has 2 Tel #s.
        int iNumEmails = 3;     // Each Account has 3 Email ids.

        strcol index;
        acc *p = NULL;

        index.list = (acc **)malloc(5 * sizeof(acc *)); // Master list  
            // of 'acc' pointers i.e. pointer to a set of pointers.

        int i, j;
        for(i=0; i<iNumAccounts; i++) // Go through the 5 Accounts, one at 
            // a time ... and allocate & store tel #s/email ids.
        {
                index.list[i] = (acc *)malloc(sizeof(acc));

                p = index.list[i];

                p->tel = (char **)malloc(iNumTels * sizeof(char*));
                for(j=0; j<iNumTels; j++)
                {
                        p->tel[iNumTels] = (char *)malloc(11 * sizeof (char)); // 10 digit tel # + 1 byte for '[=10=]' ...
                        strcpy(p->tel[iNumTels], "1234567890");
                }

                p->email = (char **)malloc(iNumEmails * sizeof(char*));
                for(j=0; j<iNumEmails; j++)
                {
                        p->email[iNumEmails] = (char *)malloc(51 * sizeof(char)); // 50 char long email id + 1 byte for '[=10=]' ...
                        strcpy(p->email[iNumEmails], "kingkong@ihop.yum");
                }
        }

        for(i=0; i<iNumAccounts; i++) // Go through the 5 Accounts, one at a time ... and display.
        {
                p = index.list[i];

                for(j=0; j<iNumTels; j++)
                {
                        printf("Tel # is: %d\n", p->tel[iNumTels]);
                }

                for(j=0; j<iNumEmails; j++)
                {
                        printf("Email id is: %s\n", p->email[iNumEmails]);
                }

                printf("----------\n");
        }
}