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

时间:2015-05-15 00:36:33

标签: c pointers data-structures struct

我有结构:

    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来保存数据电子邮件或tel

我的第一篇文章,原谅任何事情

4 个答案:

答案 0 :(得分:2)

所以这个:

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

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

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

如果对malloc()的此调用成功,您现在可以在j-1指向的空间中存储长度为(*p)->tel[0]的以空字符结尾的字符串。然后,您可以对(*p)->tel中的其他指针执行相同操作,直到(*p)->tel[i-1]

答案 1 :(得分: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);

答案 2 :(得分:0)

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

示例可能类似于下面的代码,但您最好按照 Jerry Cain 关于堆叠程序的视频(您可以在以下网址找到这些视频) youtube:斯坦福 - 编程范例视频。堆栈会话应该在视频编号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;
}

答案 3 :(得分:0)

我要假设'p'是acc * p; (我不知道'contato'是什么)。 无论如何......重点是展示如何分配内存和电话/电子邮件数据存储/访问...也复制tel#/ email id只是为了演示...... 关于从malloc返回转换void指针,我已经看到了/反对的参数...我演员(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 '\0' ...
                        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 '\0' ...
                        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");
        }
}