![](/img/trans.png)
[英]How do I use malloc for an array of structs inside another struct that has been created using malloc
[英]How do you use malloc of struct inside a function?
在這段代碼中,
#include <stdio.h>
#include <stdlib.h>
typedef struct test
{
int i;
double data;
} test;
void add(ar) struct test *ar;
{
int num = 10;
// *ar = malloc(num * sizeof(struct test)); // Adding this
for (int i = 0; i < num; i++)
{
ar[i].i = i;
ar[i].data = i * i;
}
}
int main(void)
{
test ar[10]; // Removing this
add(&ar);
for (int i = 0; i < 10; i++)
{
printf("%d %f\n", ar[i].i, ar[i].data);
}
return 0;
}
我們如何在main
定義struct
但在function
分配內存?
我想在函數add
設置數字 ( num
),因為它在main
還不知道。
有兩個值必須從add()
傳回main()
, num
和malloc()
ed 數組本身。 由於您只能返回一個值,因此有兩種情況:
a) 返回 num 並有一個test **
參數來傳回數組
int add( struct test **ar )
{
int num = 10;
*ar = malloc( num * sizeof **ar );
// initialize everything, you have to replace ar[i] by (*ar)[i]
return num;
}
叫它
struct test *ar;
int num = add( &ar );
b) 返回數組並有一個int *
參數來傳回 num
struct test *add( int *num )
{
*num = 10;
struct test *ar = malloc( *num * sizeof *ar );
// initialize everything as you do now
return ar;
}
叫它
int num;
struct test *ar = add( &num );
正如@Bodo 提到的,無論哪種方式,您都必須調用free( ar );
在main()
當您不再需要ar
。 您可以直接調用它或考慮使用像free_test( struct test *ar, int num );
這樣的清理函數free_test( struct test *ar, int num );
這樣就可以了。 如果您有更多malloc()
為單個結構元素分配內存(例如,如果它們包含用於存儲字符串的char *
元素malloc()
則此類函數特別有用。
#include <stdio.h>
#include <stdlib.h>
struct test
{
int i;
double data;
} ;
struct test *test_create(unsigned ntest)
{
struct test *pp;
unsigned idx;
pp = malloc(sizeof *pp * ntest);
for (idx = 0; idx < ntest; idx++)
{
pp[idx].i = idx;
pp[idx].data = idx * idx;
}
return pp;
}
int main(void)
{
struct test *ptr;
ptr = test_create(10);
for (int i = 0; i < 10; i++)
{
printf("%d %f\n", ptr[i].i, ptr[i].data);
}
return 0;
}
更新:如果您想返回多個項目,您可以將這些項目放在一個結構中:
#include <stdio.h>
#include <stdlib.h>
struct dope {
unsigned size;
struct {
int i;
double data;
} *array;
} ;
struct dope *dope_create(void)
{
struct dope *pp;
unsigned omg =10;
pp = malloc(sizeof *pp );
pp->array = malloc(sizeof *pp->array * omg);
pp->size = omg;
for (omg = 0; omg < pp->size; omg++)
{
pp->array[omg].i = omg;
pp->array[omg].data = omg * omg;
}
return pp;
}
int main(void)
{
struct dope *ptr;
ptr = dope_create();
for (int iii = 0; iii < ptr->size; iii++)
{
printf("%d %f\n", ptr->array[iii].i, ptr->array[iii].data);
}
return 0;
}
您已經有很好的答案作為替代方案。 無論如何,我將向您展示兩種常見的編寫方式的代碼。
正如我在您的代碼中看到的,工廠函數將確定要分配的結構test
的實際數量。 我將在示例中:
rand()
生成隨機數量的結構體,因為它在這里沒有區別因為它在所有 C 字符串中都成功使用了 :) 我們可以在這里使用它。 與字符串(C 字符串)一樣,您需要搜索終止符以獲得數組大小(當然,您可以將第一個指針設置為大小,類似於 Pascal )。 事先知道結構體的數量可能重要,也可能不重要。
Test** add_vector()
{
// returns a null terminated array of pointers
// to 'Test', pointing to actual instances of
// 'Test', allocated and numbered with 'i' starting
// at 1 and 'data' starting at 1.01
int num = rand() % 10; // 0 to 9 Test
fprintf(stderr,
"add_vector(): creating %d structs\n", num);
// at least one pointer, the terminating one
Test** ar = (Test**)malloc((1 + num) * sizeof(Test*));
int ix = 0;
for (ix = 0; ix < num; ix += 1)
{
ar[ix] = (Test*)malloc(sizeof(Test));
// sets up ar[i] to a known value
ar[ix]->i = 1 + ix;
ar[ix]->data = 1 + ix + (1 + ix) / 100.;
}; // for()
ar[ix] = NULL; // the terminator one, as in strings
return ar;
}
要使用它,您只需調用
Test** vector = add_vector();
正如您在下面的示例中看到的那樣。 返回單個指針。 不需要爭論。 如果結構數為零,則返回單個指針,就像使用空字符串一樣。
# of structs 在函數內部定義,所有的 structs 實例在返回給調用者之前都被分配和編號。
typedef struct
{
int i;
double data;
} Test;
typedef struct
{
unsigned size;
Test* test;
} V_Test;
V_Test* add_struct();
分配函數返回一個指向V_Test
結構的指針,該結構包含一個Test
結構數組和一個size
元素,每個 C 程序的 in main()
int main(in argc, char** argv)
這是代碼:
V_Test* add_struct()
{
// returns a vector of structs inside V_Test,
// with known 'size', like in main( int,char**)
// The structs are initialized with 'i' starting
// at 1 and 'data' starting at 1.01
unsigned num = rand() % 10; // 0 to 9 Test
fprintf(stderr, "add_struct(): creating %d structs\n", num);
V_Test* v = (V_Test*) malloc(sizeof(V_Test));
v->size = num;
if (num == 0)
{
v->test = NULL;
return v;
};
v->test = (Test*)malloc(num * sizeof(Test));
for (unsigned ix = 0; ix < num; ix += 1)
{
v->test[ix].i = 1 + ix;
v->test[ix].data = 1 + ix + (1 + ix) / 100.;
}; // for()
return v;
}
要使用它,您只需調用
V_Test* vector = add_struct();
在這里也沒有爭論。 分配並返回一個新的V_Test
。
同樣,這里的# of structs 是在函數內部定義的,所有的structs 實例在返回給調用者之前都被分配和編號。
在代碼中,您將看到使用這兩個函數的方法,創建結構,填充它們,顯示內容並釋放分配的內存。
add_vector(): creating 9 structs
# 1: [1, 1.01]
# 2: [2, 2.02]
# 3: [3, 3.03]
# 4: [4, 4.04]
# 5: [5, 5.05]
# 6: [6, 6.06]
# 7: [7, 7.07]
# 8: [8, 8.08]
# 9: [9, 9.09]
9 records were created
9 records were free()'d
add_struct(): creating 4 structs
# 1: [1, 1.01]
# 2: [2, 2.02]
# 3: [3, 3.03]
# 4: [4, 4.04]
4 records were created
4 records were free()'d
我只在 MSVC 下編譯過一次。
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int i;
double data;
} Test;
typedef struct
{
unsigned size;
Test* test;
} V_Test;
V_Test* add_struct();
Test** add_vector();
void as_vector_of_pointers();
void as_struct_of_struct();
int main(void)
{
srand(210728);
as_vector_of_pointers();
as_struct_of_struct();
return 0;
}
Test** add_vector()
{
// returns a null terminated array of pointers
// to test
int num = rand() % 10; // 0 to 9 Test
fprintf(stderr,
"add_vector(): creating %d structs\n", num);
// at least one pointer, the terminating one
Test** ar = (Test**)malloc((1 + num) * sizeof(Test*));
int ix = 0;
for (ix = 0; ix < num; ix += 1)
{
ar[ix] = (Test*)malloc(sizeof(Test));
// sets up ar[i] to a known value
ar[ix]->i = 1 + ix;
ar[ix]->data = 1 + ix + (1 + ix) / 100.;
}; // for()
ar[ix] = NULL; // the terminator one, as in strings
return ar;
}
V_Test* add_struct()
{
// returns a vector of structs inside V_Test,
// with known 'size', like in
// main( int,char**)
unsigned num = rand() % 10; // 0 to 9 Test
fprintf(stderr, "add_struct(): creating %d structs\n", num);
V_Test* v = (V_Test*) malloc(sizeof(V_Test));
v->size = num;
if (num == 0)
{
v->test = NULL;
return v;
};
v->test = (Test*)malloc(num * sizeof(Test));
for (unsigned ix = 0; ix < num; ix += 1)
{
v->test[ix].i = 1 + ix;
v->test[ix].data = 1 + ix + (1 + ix) / 100.;
}; // for()
return v;
}
void as_struct_of_struct()
{
V_Test* vector = add_struct();
if (vector->size == 0)
{
printf("No records were created!\n");
free(vector);
return;
}
for ( unsigned count = 0; count < vector->size; count+=1)
{
printf("#%3d: [%d, %.2f]\n",
1 + count,
vector->test[count].i,
vector->test[count].data
);
}; // for()
printf("%d records were created\n", vector->size);
// to free() vector:
free(vector->test);
printf("%d records were free()'d\n", vector->size);
free(vector);
return;
};
void as_vector_of_pointers()
{
Test** vector = add_vector();
// now test the vector to count the number of
// records generated in the funcion
if (vector[0] == NULL)
{
printf("No records were created!\n");
free(vector);
return;
}
unsigned count = 0;
while (vector[count] != NULL)
{
printf("#%3d: [%d, %.2f]\n", 1 + count, (vector[count])->i,
(vector[count])->data);
count += 1;
};
printf("%d records were created\n", count);
// to free() vector, same way:
for (unsigned i = 0; i < count; i += 1) free(vector[i]);
free(vector);
printf("%d records were free()'d\n", count);
return;
}
所以警惕:我總是投
malloc()
指針,因為我提醒自己和其他閱讀代碼的人。 沒有隱式轉換。 沒有必要指出這一點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.