为具有指针成员的指针结构分配内存

Allocating memory for pointer struct which has pointer members

我正在尝试使用具有指针成员的结构指针来读取和打印。所以我正在尝试读取和打印双结构指针数组。 我尝试了以下操作,但它给我的错误是 "Access violation writing location (somewhere in memory)"

如何为此动态分配内存?

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <stdio.h>
#include<string.h>
#include <stdlib.h>

typedef struct template{
char *name;
int  *birthdate;
int *phoneNum;

} detailsOf;

void inputValue(detailsOf **person, int maxSize);

int main() {

detailsOf **person;
int maxSize = 0, menu = 0;

printf("Max:");
scanf("%d", &maxSize);


person = (detailsOf **)malloc(maxSize * sizeof(detailsOf **));
if (person == NULL) {
    printf("Failed to allocate");
    exit(0);
}
for (int i = 0; i < maxSize; i++) {
    person[i]->name = (char *)calloc(21, sizeof(char ));
    person[i]->birthdate = (int *)calloc(8, sizeof(int ));
    person[i]->phoneNum = (int *)calloc(16, sizeof(int ));
}

inputValue(person, maxSize);

for (int i = 0; i < maxSize; i++) {
    free(person[i]);
    for (int j = 0; j < 21; j++) {
        free(person[i]->name[j]);
    }
    for (int j = 0; j < 15; j++) {
        free(person[i]->phoneNum[j]);
    }
    for (int j = 0; j < 8; j++) {
        free(person[i]->birthdate[j]);
    }
}
    return 0;
}
void inputValue(detailsOf **person, int maxSize) {
    for (int i = 0; i < maxSize; i++) {
        printf("Name of %d", i + 1);
        scanf("%s", person[i]->name);
          for (int j = 0; j < 8; j++) {
             printf("Birth %d:", i + 1);
             scanf("%d", person[i]->birthdate[j]);
     } 
     for (int k = 0; k < 8; k++) {
         printf("Phone %d:", i + 1);
         scanf("%d", person[i]->phoneNum[k]);
      }
   }
    printf("SUCCESS\n");
}

规则很简单——一个指针是未初始化直到它有一个有效的地址分配给它,或者内存已经被分配用于存储东西和起始地址分配给它的新内存块。

您为 person 分配了 maxSize 指针 ,但在分配之前未能为每个 person[i] 分配一个 struct对于 name,等..

所以你必须分配一个结构,例如pointer[i] = malloc (sizeof *pointer[i]) 在尝试分配 person[i]->name = calloc(21, sizeof(char )); 之前,...

另请注意,如果您根据取消引用的指针的大小进行分配——您的分配将永远不会出错,(您的 person 分配仅作为意外事故的结果是正确的),相反,例如

person = malloc (maxSize * sizeof *person);
...
person[i] = malloc (sizeof *person[i]);

(注意 []-> 算作取消引用)

person[i]->name = calloc (21, sizeof *person[i]->name);

不需要投malloc的return,没必要。参见:Do I cast the result of malloc?

person = (detailsOf **)malloc(maxSize * sizeof(detailsOf **));

应该是

person = malloc(maxSize * sizeof(detailsOf *));

然后,这会分配内存来保存指向 detailsOf 的指针,但您永远不会为每个 detailsOf

分配内存
for(int i=0; i<maxSize; i++)
{
   person[i]=malloc(sizeof(detailsOf));
}

另外你释放的内存应该是

for (int i = 0; i < maxSize; i++)
{
    free(person[i]->name);
    free(person[i]->phoneNum);
    free(person[i]->birthdate);
    free(person[i]);
}
free(person);

请记住,释放时只需将您的 free 调用与 malloc 调用相匹配即可。

person = (detailsOf **)malloc(maxSize * sizeof(detailsOf **));

这分配了一个双指针数组,类型为 detailsOf,数组大小为 maxSize

sizeof(detailsOf**) 是一个地址的大小,它不会给你你的用户定义数据类型的大小 detailsOf.

另外,双指针的意思是,它是一个地址位置,它将存储另一个指针的地址,该指针指向detailsOf

的内存位置
/* if you want to use double pointer then */
detailsOf **dptr;  // two dimensional array of detailsOf */
detailsOf *sptr;   /* one dimentional array of detailsOf */

/* This allocates the memory for storing 3 detailsOf struct data */
sptr = malloc(3 * sizeof(detailsOf)); 
dptr = &sptr;

/* Now to access double ptr */
for (int i = 0; i < 3; ++i) {
    dptr[0][i].birthdate = malloc(3 * sizeof(int));
}

for (int i = 0; i < 3; ++i) {
    dptr[0][i].birthdate[0] = i; 
    dptr[0][i].birthdate[1] = i + 10; 
    dptr[0][i].birthdate[2] = i + 1990; 
}

for (int i = 0; i < 3; ++i) {
    printf("%d\", dptr[0][i].birthdate[0]); 
    printf("%d\", dptr[0][i].birthdate[1]); 
    printf("%d\n", dptr[0][i].birthdate[2]); 
}

/* Not to free the double pointer,
 * you have to free the inner pointer first then the outer pointers
 * Easy to remember is to free in reverse order of your allocation order
 */
for (int i = 0; i < 3; ++i) {
    free(dptr[0][i].birthdate);
    free(dptr[0]);
    /* free(dptr); this is not needed in this example because
     * dptr is pointer to address of a local variable,
     * but if it points to address of another array of detailOf* 
     * then this free is needed
     */ 
}

在你的例子中,你只有一个指针数组而不是双指针数组。