动态分配的结构数组传递给函数并通过索引

时间:2016-10-18 07:17:22

标签: c memory-management dynamic-allocation

我正在尝试通过将指针传递给函数来动态分配结构数组。我需要使用索引来访问数组。我有一个类似的过程在没有传递给函数的情况下工作。我有一个名为Account的简单结构,它只有一个成员accountNo。下面列出的是相关的malloc调用

int8_t dynamicStruct(struct Account **all_accounts,int8_t num_accounts){
    *all_accounts = (struct Account*)malloc(sizeof(struct Account)*num_accounts);
}

变量all_accounts已初始化并使用以下代码段调用,此时num_accounts为10;

struct Account *all_accounts_dyn;
dynamicStruct(&all_accounts_dyn,num_accounts);

使用以下方法访问成员变量accountNo

all_accounts[i]->accountNo = i;

程序编译正常,设法分配内存,但在访问成员时会出现段错误(num_accounts = 10)。

编译

gcc -std=gnu99 -Wall -Werror structify.c -o structify

“小型自包含示例”

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>

struct Account{
    int8_t accountNo;
};
int8_t dynamicStruct(struct Account **all_accounts,int8_t num_accounts);

int main(){
    struct Account *all_accounts_dyn;
    int8_t num_accounts = 10;
    dynamicStruct(&all_accounts_dyn,num_accounts);
    return 1;
}
int8_t dynamicStruct(struct Account **all_accounts,int8_t num_accounts){
        *all_accounts = (struct Account*)malloc(sizeof(struct Account)*num_accounts);
        for(int i = 0; i<num_accounts;i++){
            printf("initializing %d\n",i);
            all_accounts[i]->accountNo = i;
        }
        return 1;
}

4 个答案:

答案 0 :(得分:2)

当您拥有struct my_struct;时,您可以访问以下成员:

mystuff = my_struct.stuff;

但是当你有一个指向结构struct *my_struct;的指针时,你会这样做:

mystuff = my_struct->stuff;

这相当于:

mystuff = (*my_struct).stuff;

换句话说,在访问其成员字段之前,必须取消引用struct的指针。

为10个结构分配内存时:

*all_accounts = (struct Account*)malloc(sizeof(struct Account)*num_accounts);

然后使用数组表示法访问,您有all_accounts[i] ==> *(all_accounts + i)。因此,all_accounts[i]是一个结构,而不是指向结构的指针,必须使用点运算符进行访问。

答案 1 :(得分:2)

正如您所写,为您使用的all_accounts_dyn分配空间

*all_accounts = malloc(sizeof(struct Account)*num_accounts);

由于双指针,它是正确的。

双指针采用指针all_accounts_dyn

的地址

malloc的返回地址已分配给all_accounts_dyn *all_accountsdynamicStruct的{​​{1}}。

因此,当您循环到init结构时,您必须首先取消引用双指针和取消引用all_accounts_dyn项。

    for(int i = 0; i<num_accounts;i++)
    {
        (*all_accounts)[i].accountNo = i;

        printf("initialized %d\n", (*all_accounts)[i].accountNo);

    }

答案 2 :(得分:-1)

如果您正在尝试分配结构的araay,那么为什么使用双指针。

all_acounts =(Acount *)malloc(sizeof(Acount)* num_acounts)并在函数dynamicStruct中将参数设置为普通非双指针* all_acounts

答案 3 :(得分:-1)

the posted code contains several problems.

  1. incorrect return value from main()
  2. unused return value from dynamicStruct()
  3. using wrong type when passing num_accounts
  4. needs appropriate vertical and horizontal spacing, for readability
  5. does not properly set the values in the array of structs
  6. fails to check for errors in call to malloc()
  7. contains several risky conversions between different numeric types
  8. contains tabs for indenting the code
  9. does not indent the code consistently
  10. returns a misleading value from the main() function
  11. casts the returned value from malloc(), which is a bad practice in C

and now the corrected code:

#include <stdio.h>   // printf()
#include <stdint.h>  // int8_t 
#include <stdlib.h>  // malloc(), exit(), EXIT_FAILURE
//#include <stdbool.h>

struct Account
{
    int8_t accountNo;
};

void dynamicStruct( struct Account **all_accounts, size_t num_accounts );

int main( void )
{
    struct Account *all_accounts_dyn;
    size_t num_accounts = 10;
    dynamicStruct( &all_accounts_dyn, num_accounts );
} // end function: main


void dynamicStruct( struct Account **all_accounts, size_t num_accounts )
{
        *all_accounts = malloc(sizeof(struct Account)*num_accounts);
        if( NULL == *all_accounts )
        {
            perror( "malloc for account array failed" );
            exit( EXIT_FAILURE );
        }

        // implied else, malloc successful


        for( int8_t i = 0; i<(int8_t)num_accounts; i++ )
        {
            printf("initializing %d\n",i);
            (*all_accounts)[i].accountNo = i;
        }
} // end function: dynamicStruct

The above code outputs the following:

initializing 0
initializing 1
initializing 2
initializing 3
initializing 4
initializing 5
initializing 6
initializing 7
initializing 8
initializing 9