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

Dynamically allocated array of structs passed to function and accessed with indexing

我正在尝试通过将指针传递给函数来动态分配结构数组。我需要使用索引访问数组。我有一个类似的过程在不传递给函数的情况下工作。我有一个名为 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

"Small self contained example"

#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;
}

如果你试图分配一个结构数组,那你为什么要使用双指针。

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

当你有 struct my_struct; 时,你可以这样访问成员:

mystuff = my_struct.stuff;

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

mystuff = my_struct->stuff;

这相当于:

mystuff = (*my_struct).stuff;

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

当您为 10 个结构分配内存时:

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

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

如您所写,为 all_accounts_dyn 分配 space 您使用了

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

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

双指针取指针地址all_accounts_dyn

malloc的返回地址赋值给了all_accounts_dyn,也就是dynamicStruct函数内部的*all_accounts

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

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

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

    }

发布的代码包含几个问题。

  1. 来自 main()
  2. 的 return 值不正确
  3. 未使用 return 来自 dynamicStruct()
  4. 的值
  5. 传递时使用了错误的类型 num_accounts
  6. 需要适当的垂直和水平间距,以提高可读性
  7. 没有正确设置结构数组中的值
  8. 无法检查对 malloc()
  9. 的调用中的错误
  10. 包含几个不同数值类型之间的风险转换
  11. 包含用于缩进代码的制表符
  12. 代码缩进不一致
  13. returns 来自 main() 函数的误导值
  14. malloc() 转换 returned 值,这在 C
  15. 中是一种不好的做法

现在是更正后的代码:

#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

以上代码输出如下:

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