这是初始化指向struct的指针的正确方法吗?谢谢

问题描述

如何创建用于构造正确方法的指针?

typedef struct account{

char name[80];

int acct_year;

}account;

int main
{
account *accountant;// is this the proper way?
}

解决方法

我在代码中写了注释来解释事情。 让我知道是否仍然感到困惑。


#include <stdio.h>

// This is needed for strncpy
#include <string.h>

// This is needed for malloc
#include <stdlib.h>

struct Account {
    char name[80];
    int acct_year;
};

int main()
{
    // Normal declaration of a variable of type Account
    struct Account userAccount;


    // Using strncpy is safer than using strcpy. Read about overflow buffer attack.
    char* userName = "Alex";
    strncpy(userAccount.name,userName,sizeof(userName));
    
    userAccount.acct_year = 4;
    printf("User Account: %s %d\n",userAccount.name,userAccount.acct_year);
    
    // Creating a pointer to access the struct we declare and initiate above;
    struct Account *pUserAccount;
    
    // Pass the address of the variable above inside the pointer
    pUserAccount = &userAccount; 
    
    // We can replace the value in userAccount from the pointer
    pUserAccount->acct_year = 5; 
    
    // Compare to see that we changed the value in userAccount using the pointer
    printf("Pointer User Account: %s %d\n",pUserAccount->name,pUserAccount->acct_year);
    printf("User Account: %s %d\n",userAccount.acct_year);
    
    
    // Let's create a pointer and give it some space from the Heap memory
    struct Account *pAdminAccount;
    pAdminAccount = malloc(sizeof (struct Account));
    
    // We always check because we could have run out of memory or something failed
    if (pAdminAccount != NULL) {
        // Due my lazyness,I am copying the name from userAccount inside pAdminAccount
        strncpy(pAdminAccount->name,sizeof(userAccount.name));
        pAdminAccount->acct_year = 6;
        printf("Pointer Heap Adminr Account: %s %d\n",pAdminAccount->name,pAdminAccount->acct_year);
    
        // Always free the memory when you are not using it.    
        free(pAdminAccount);
    }
    
    return 0;
}

注意:我已经很久没有做C了,所以请仔细检查我在这里解释的内容。

说明:

因此,可以使用多种方法来使用结构。

第一种使用方式类似于int,char,bool等任何其他类型。

如果我执行int a; a = 4;,则将提供来自堆栈的内存,该内存将在已声明的块内可用。因此,如果在函数内部创建它,则即使您使用&返回该变量的地址,它也将一直可用,直到您退出该函数。不要这样做。

因此,struct Account userAccount;将创建一个变量,您可以立即使用它:userAccount.acct_year = 4;

如果希望使用指针间接访问,则需要创建指针struct Account *pUserAccount;。在此指针中,我们以这种方式保存userAccount的地址:pUserAccount = &userAccount。请注意,由于我们没有访问权限,因此我没有使用*

使用此方法的优点是编译器知道我们所指向的大小。稍后,当您熟悉这一点时,您可以使用一系列结构以及如何使用指针访问它们。

无论如何,继续说明。

例如,如果您希望拥有一个创建帐户的功能并在功能之外使用该帐户,则必须使用mallocmalloc从堆中获取内存,并将地址返回到该内存位置。

您必须告诉malloc要保留多少内存:sizeof (struct Account)

如前所述,malloc(sizeof (struct Account));将返回一个地址。 现在,您可以从函数中返回该地址或立即使用它。

请务必检查NULL,因为malloc可能无法获得备用内存(即内存不足)。

此外,这对您自己进行清理很重要。释放您在堆中占用的内存,以便其他程序也可以使用它。这样可以避免很多问题,例如内存分段等。

您可以将其声明为struct Account userAccount;,并在块的整个生命周期内自动分配内存。如果声明

,

关于如何初始化已声明的指针,您有两个选择。举个例子:

typedef struct account {
    char name[80];
    int acct_year;
} account;

int main (void)
{
    account *accountant;
}

以上,accountant是一个未初始化的指针,该指针保存一个不确定的(可以是任何东西)地址作为其值。要初始化指针,您必须(1)向其分配现有类型account的地址,例如

int main (void)
{
    account account1 = { "Client A",2019 };     /* object of type account */
    account *accountant = &account1;             /* address assigned to pointer */
    
    /* use accountant as needed */
    printf ("\naccountant: %s (%d)\n",accountant->name,accountant->acct_year);
}

或者,(2)使用accountantmalloccallocrealloc动态分配存储空间,例如

int main (void)
{
    account *accountant = malloc (sizeof *accountant);  /* allocate for 1 account */
    
    if (accountant == NULL) {                           /* validate every allocation */
        perror ("malloc-accountant");
        return 1;
    }
    
    strcpy (accountant->name,"Client A");
    accountant->acct_year = 2019;
    
    /* use accountant as needed */
    printf ("\naccountant: %s (%d)\n",accountant->acct_year);

    free (accountant);                                 /* free what you allocate */
}

任何一种都可以。指针只是一个普通变量,它保存 address 的地址,其他内容作为其值存储在内存中。换句话说,指针指向可以找到其他内容的地址。您必须确保指针所保存的地址的值指向其持有该类型对象的有效内存地址。如果您总是问“我的指针在哪里?”在使用它之前-您再也不会遇到指针问题了。

,

通常的方法是使用malloc()系统调用分配一个内存块 将您的结构类型放到系统堆上。您将要检查 如果您的内存不足,这实际上是发生了。

    account * accountant;
    
    if ((accountant = malloc ( sizeof(struct account))) == NULL)
    {
              errno = ENOMEM;
              return some error token.
    }

...continue knowing the pointer has been initialised.

完成后,请确保使用以下方法将块释放回系统中

free (accountant);