为具有指针成员的指针结构分配内存
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
*/
}
在你的例子中,你只有一个指针数组而不是双指针数组。
我正在尝试使用具有指针成员的结构指针来读取和打印。所以我正在尝试读取和打印双结构指针数组。 我尝试了以下操作,但它给我的错误是 "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
*/
}
在你的例子中,你只有一个指针数组而不是双指针数组。