如何在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");
}
}
我有结构:
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");
}
}