我对 C 中的常见问题之一感到困惑,即内存管理和指针。我有三个结构,像这样。
typedef struct {
uint8_t uuid[16];
} uuid_array;
typedef struct Detail {
int8_t power;
uint32_t t1;
uint32_t dT;
} Detail_t;
typedef struct Base {
uuid_array unique_id;
Detail_t *data;
} Base_t;
我想创建十个Base_t
结构,我希望data
每个结构中的指针Base_t
struct
指向一个动态增长的Detail_t
结构数组。
我知道我应该使用malloc()
,realloc()
但我没有使用这些功能的经验,我对它们的工作方式感到非常困惑。
data
指针如何指向动态大小的Detail_t
struct
s数组?
非常感谢你。
这是另一种方式...
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
typedef struct
{
uint8_t uuid[16];
} uuid_array;
typedef struct Detail
{
int8_t power;
uint32_t t1;
uint32_t dT;
} Detail_t;
typedef struct Base
{
uuid_array unique_id;
Detail_t *data;
uint32_t dataItemCnt; /* In struct Base you will want to add an item int **
** n_dataItems to keep track of how many items **
** there are in your array. – Paul Ogilvie */
} Base_t;
#define SUCCESS 0
/**********************************************************
** Append a Detail_t structure to the data field of the to Base_t structure..
*/
int AppendData(Base_t *baseT, int8_t power, uint32_t t1, uint32_t dT)
{
int rCode = SUCCESS;
Detail_t *data=NULL;
/* Verify that the caller did not pass NULL as the Base_t structure address. */
if(!baseT)
{
rCode=EINVAL; /* Invalid Base_t value argument. */
goto CLEANUP;
}
/* Increase the size of the baseT->data array sufficient for an additional Detail_t structure. */
errno=SUCCESS;
data=realloc(baseT->data, (baseT->dataItemCnt + 1) * sizeof(Detail_t));
if(!data) /* Verify that the realloc() succeeded. */
{
rCode=errno;
goto CLEANUP;
}
/* Cause the Base_t data array to point to the newly (re-alloced) memory. */
baseT->data = data;
/* Initialize the new Detail_t structure values. */
baseT->data[baseT->dataItemCnt].power = power;
baseT->data[baseT->dataItemCnt].t1 = t1;
baseT->data[baseT->dataItemCnt].dT = dT;
/* Increment Base_t->dataItemCnt to reflect the appended Detail_t structure. */
++baseT->dataItemCnt;
CLEANUP:
return(rCode);
}
/**********************************************************
** Free a previously allocated Base_t type.
*/
int FreeBaseT(Base_t **baseT)
{
int rCode = SUCCESS;
/* Verify that the caller did not pass in NULL for baseT */
if(!baseT)
{
rCode=EINVAL; /* Invalid Base_t value argument. */
goto CLEANUP;
}
/* verify that the the Base_t structure is not already free. */
if(!*baseT)
{
rCode=EALREADY; /* The Base_t structure is NULL (Already free). */
goto CLEANUP;
}
/* If there are Detail_t structures in the data array, free the data array. */
if((*baseT)->data)
free((*baseT)->data);
/* Free the memory previously allocated to the Base_t structure. */
free(*baseT);
*baseT = NULL; /* Eliminate the caller's reference to the freed memory. */
CLEANUP:
return(rCode);
}
/**********************************************************
** Allocate a Base_t type.
*/
int AllocBaseT(Base_t **baseT_OUT, uint8_t uuid[16])
{
int rCode = SUCCESS;
Base_t *baseT = NULL;
/* Allocate memory to the Base_t structure. */
errno=SUCCESS;
baseT = malloc(sizeof(Base_t));
if(!baseT)
{
rCode=errno;
goto CLEANUP;
}
/* Initialize the initial values of the Base_t structure. */
memset(baseT, 0, sizeof(Base_t));
memcpy(&baseT->unique_id.uuid, uuid, 16);
/* Ensure that the caller passed a non-NULL address,
if so, return the address of the allocated Base_t structure. */
if(baseT_OUT)
{
*baseT_OUT = baseT;
baseT = NULL;
}
CLEANUP:
/* If the caller passed-in a NULL for baseT_OUT,
free the allocated memory to that the program does not cause a leak. */
if(baseT)
{
int rc=FreeBaseT(&baseT);
if(rc && !rCode)
rCode=rc;
}
return(rCode);
}
/**********************************************************
** Dump a base_t structure.
*/
int DumpBaseT(Base_t *baseT)
{
int rCode = SUCCESS;
uint32_t index;
if(!baseT)
{
rCode=EINVAL; /* Invalid Base_t value argument. */
goto CLEANUP;
}
/* Print the Base_t->unique_array->uuid */
printf("UUID: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
baseT->unique_id.uuid[0],
baseT->unique_id.uuid[1],
baseT->unique_id.uuid[2],
baseT->unique_id.uuid[3],
baseT->unique_id.uuid[4],
baseT->unique_id.uuid[5],
baseT->unique_id.uuid[6],
baseT->unique_id.uuid[7],
baseT->unique_id.uuid[8],
baseT->unique_id.uuid[9],
baseT->unique_id.uuid[10],
baseT->unique_id.uuid[11],
baseT->unique_id.uuid[12],
baseT->unique_id.uuid[13],
baseT->unique_id.uuid[14],
baseT->unique_id.uuid[15]
);
/* Print the Base_t->Detail_t values */
printf("Number of data items: %u\n", baseT->dataItemCnt);
for(index=0; index < baseT->dataItemCnt; ++index)
{
printf(" data[%d] power=%d t1=%d dT=%d\n",
index,
baseT->data[index].power,
baseT->data[index].t1,
baseT->data[index].dT
);
}
CLEANUP:
return(rCode);
}
/**********************************************************
** Program start.
*/
int main(int argC, char *argV[])
{
int rCode = SUCCESS;
Base_t *baset_A = NULL;
uint8_t uuid[16] =
{
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10
};
/* Allocate memory for a Base_t structure (with no attached data) */
rCode=AllocBaseT(&baset_A, uuid);
if(rCode)
{
fprintf(stderr, "AllocBaseT() reports: %d %s\n", rCode, strerror(rCode));
goto CLEANUP;
}
/* Allocate some data (Detail_t) to the Base_t structure. */
rCode=AppendData(baset_A, 1, 1000, 1111);
if(rCode)
{
fprintf(stderr, "AppendData() reports: %d %s\n", rCode, strerror(rCode));
goto CLEANUP;
}
rCode=AppendData(baset_A, 2, 2000, 2222);
if(rCode)
{
fprintf(stderr, "AppendData() reports: %d %s\n", rCode, strerror(rCode));
goto CLEANUP;
}
rCode=AppendData(baset_A, 3, 3000, 3333);
if(rCode)
{
fprintf(stderr, "AppendData() reports: %d %s\n", rCode, strerror(rCode));
goto CLEANUP;
}
/* Print out the Base_t structure. */
rCode=DumpBaseT(baset_A);
if(rCode)
{
fprintf(stderr, "DumpBaseT() reports: %d %s\n", rCode, strerror(rCode));
goto CLEANUP;
}
CLEANUP:
/* Free the memory allocated to the Base_t structure. */
if(baset_A)
{
int rc=FreeBaseT(&baset_A);
if(rc)
fprintf(stderr, "FreeBaseT() reports: %d %s\n", rCode, strerror(rCode));
}
return(rCode);
}
输出:
UUID: 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10
Number of data items: 3
data[0] power=1 t1=1000 dT=1111
data[1] power=2 t1=2000 dT=2222
data[2] power=3 t1=3000 dT=3333
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句