简体   繁体   English

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

[英]is this the proper way to initialize a pointer to struct? thank you

how to create a pointer to struct the proper way?如何创建一个指针来构造正确的方法?

typedef struct account{

char name[80];

int acct_year;

}account;

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

I wrote comments in the code to explain things.我在代码中写了注释来解释事情。 Let me know if still confusing.如果仍然令人困惑,请告诉我。


#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.name, 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, userAccount.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;
}

Note: I haven't done C in ages so double check what I am explaining here.注意:我已经很久没有使用 C 语言了,所以请仔细检查我在这里解释的内容。

Explanation:解释:

So, there are different ways that you can use a struct.因此,您可以通过多种方式使用结构体。

The first way to use is is like any other type such as int, char, bool, etc.第一种使用方式就像任何其他类型,如 int、char、bool 等。

If I do int a; a = 4;如果我做int a; a = 4; int a; a = 4; , memory from the stack is provided that will be available inside the block it has being declared. ,提供来自堆栈的内存,这些内存将在已声明的块内可用。 So, if you create it inside a function, it will be available until you exit the function, even if you return the address of such variable using & .因此,如果您在函数内创建它,它在退出函数之前一直可用,即使您使用&返回此类变量的地址。 Don't do it.不要这样做。

So, struct Account userAccount;所以, struct Account userAccount; will create a variable that you can right away use it: userAccount.acct_year = 4;将创建一个您可以立即使用它的变量: userAccount.acct_year = 4;

If you wish to access indirectly using a pointer, then you need to create a pointer struct Account *pUserAccount;如果您希望使用指针间接访问,那么您需要创建一个指针struct Account *pUserAccount; . . In this pointer, is where we save the address of userAccount in this way: pUserAccount = &userAccount .在这个指针中,我们以这种方式保存userAccount的地址: pUserAccount = &userAccount Notices that I didn't use the * since we are not accessing.请注意,我没有使用*因为我们没有访问。

The advantage of using this method is that the compiler knows the size of what we are pointing at.使用这种方法的好处是编译器知道我们指向的东西的大小。 Later, when you are familiar with this, you can play with an array of structs and how to access them using pointers.稍后,当您熟悉这一点时,您可以使用结构数组以及如何使用指针访问它们。

Anyways, continue with the explanation.不管怎样,继续解释。

If you wish for example to have a function that creates an account and using such account outside a function, then you must use malloc .例如,如果您希望有一个函数来创建一个帐户并在函数之外使用这样的帐户,那么您必须使用malloc malloc fetch memory from the Heap and return an address to such memory location. mallocmalloc获取内存并将地址返回到该内存位置。

You must tell malloc how much memory you wish to reserve: sizeof (struct Account) .您必须告诉malloc您希望保留多少内存: sizeof (struct Account)

As explained, malloc(sizeof (struct Account));如前所述, malloc(sizeof (struct Account)); will return an address.将返回一个地址。 Now, you can return that address from your function or use it right away.现在,您可以从函数中返回该地址或立即使用它。

Its important that you check for NULL since malloc might fail to get reserve memory (ie out of memory).检查NULL很重要,因为malloc可能无法获得保留内存(即内存不足)。

Also, its important for you to clean up after yourself.此外,对您来说,自己清理干净也很重要。 Free the memory you have taken in the Heap so other programs can use it too.释放您在堆中占用的内存,以便其他程序也可以使用它。 This will prevent many issues such as memory segmentation and such.这将防止许多问题,例如内存分段等。

You can declare it as struct Account userAccount;您可以将其声明为struct Account userAccount; and automatically memory will be allocated in the whole life of the block.并且会在块的整个生命周期中自动分配内存。 If the declaration of the如果声明的

You have two options on how you Initialize a declared pointer.关于如何初始化声明的指针,您有两种选择。 Take your example:举个例子:

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

int main (void)
{
    account *accountant;
}

Above, accountant is an Uninitialized pointer that holds an indeterminate (could be anything) address as its value.上面, accountant是一个未初始化的指针,它持有一个不确定(可以是任何)地址作为它的值。 To initialize the pointer, you must either (1) assign the address of an existing type account to it, eg要初始化指针,您必须(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);
}

Or, (2) dynamically allocate storage for accountant with malloc , calloc or realloc , eg或者,(2)使用malloccallocreallocaccountant动态分配存储,例如

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->name, accountant->acct_year);

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

Either way is fine.无论哪种方式都很好。 A pointer is simply a normal variable that holds the address where something else is stored in memory as its value.指针只是一个普通变量,它保存其他东西作为其值存储在内存中的地址 In other words, a pointer points to the address where something else can be found.换句话说,一个指针指向可以找到其他东西的地址。 You have to make sure that address the pointer holds as its value points to a valid memory address holding an object of that type.您必须确保指针持有的地址作为其值指向持有该类型对象的有效内存地址。 If you always ask "Where does my pointer point?"如果你总是问“我的指针指向哪里?” before using it -- you will never have trouble with pointers again.在使用它之前——你再也不会遇到指针问题了。

The usual way is to use the malloc() system call to allocate a block of memory big nough for your structure type onto the system heap.通常的方法是使用 malloc() 系统调用将一块对于您的结构类型来说不够大的内存块分配到系统堆上。 You will want to check that actually happened in case you are out of memory.如果您的内存不足,您将需要检查实际发生的情况。

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

...continue knowing the pointer has been initialised.

When you are finished MAKE SURE you free the block back to the system with完成后,请确保将块释放回系统

free (accountant);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM