【发布时间】:2021-03-16 21:24:57
【问题描述】:
我有一个指向结构 (person_t) 的全局动态指针数组 (iterator)。首先,我为 iterator 分配了 10*sizeof(person_t*) 内存,在里面我为每个 iterator[i] i = 0..9 分配了 sizeof(person_t) 内存。
typedef struct Person
{
char name[30];
unsigned age;
char job[30];
} person_t;
person_t **iterator;
int size = 10;
int count = 0;
int main()
{
int i;
iterator = malloc(size * sizeof(person_t *));
if (iterator == NULL)
{
/*fprintf(stderr, "Memory allocation did not succeed\n");*/
exit(1);
}
for (i = 0; i < size; ++i)
{
iterator[i] = malloc(sizeof(person_t));
if (iterator[i] == NULL)
{
/*fprintf(stderr, "Memory allocation did not succeed\n");*/
exit(1);
}
}
}
在我达到最大容量之前一切正常。发生这种情况时,我尝试重新分配 iterator 以获得更多内存,但它似乎不起作用,尽管我没有收到任何类型的警告或错误编译(我使用 gcc -ansi -pedantic -W -Wall -Wextra 编译)和 realloc不返回 NULL。这就是一切发生的地方:
void grow()
{
int i;
size += 5;
iterator = realloc(iterator, size);
if (iterator == NULL)
{
/*fprintf(stderr, "Memory allocation did not succeed\n");*/
exit(1);
}
printf("realloced to bigger\n");
for (i = size - 5; i < size; ++i)
{
iterator[i] = malloc(sizeof(person_t));
if (iterator[i] == NULL)
{
/*fprintf(stderr, "Memory allocation did not succeed\n");*/
exit(1);
}
}
}
当我尝试在调用 grow() 之前列出我的数据时,一切都很好。在 grow() 之后,可能会打印前 3 个结构(第一个被搞砸了),然后我得到 Segmentation fault。
如果有帮助,这里是完整的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Person
{
char name[30];
unsigned age;
char job[30];
} person_t;
person_t **iterator;
int size = 10;
int count = 0;
void newPerson();
void grow();
void list();
void del();
int main()
{
int i;
iterator = malloc(size * sizeof(person_t *));
if (iterator == NULL)
{
/*fprintf(stderr, "Memory allocation did not succeed\n");*/
exit(1);
}
for (i = 0; i < size; ++i)
{
iterator[i] = malloc(sizeof(person_t));
if (iterator[i] == NULL)
{
/*fprintf(stderr, "Memory allocation did not succeed\n");*/
exit(1);
}
}
while (1)
{
char menuChoice = ' ';
scanf("%c", &menuChoice);
switch (menuChoice)
{
case 'a':
newPerson();
break;
case 'l':
list();
break;
case 'x':
for (i = 0; i < size; ++i)
{
free(iterator[i]);
}
free(iterator);
exit(0);
case 'd':
del();
break;
case '\n':
break;
default:
fprintf(stderr, "\'a\' -add, \'l\' -list, \'d\' -delete, \'x\' -exit\nOnly these inputs are allowed\n");
break;
}
}
return 0;
}
void newPerson()
{
unsigned a = 0;
char strN[30];
char strJ[30];
int err;
if (count == size)
grow();
/*printf("Name: ");*/
scanf("%s", strN);
if ((strlen(strN) + 1) > 30)
{
do
{
fprintf(stderr, "Maximum 30 characters are allowed\n");
scanf("%s", strN);
} while ((strlen(strN) + 1) > 30);
}
/*printf("Age: ");*/
err = scanf("%u", &a);
if (err != 1)
{
do
{
printf("Only numbers are allowed\n");
fgetc(stdin);
err = scanf("%u", &a);
} while (err != 1);
}
/*printf("Job: ");*/
scanf("%s", strJ);
if ((strlen(strJ) + 1) > 30)
{
do
{
fprintf(stderr, "Maximum 30 characters are allowed\n");
scanf("%s", strJ);
} while ((strlen(strJ) + 1) > 30);
}
iterator[count]->age = a;
strcpy(iterator[count]->name, strN);
strcpy(iterator[count]->job, strJ);
count++;
}
void list()
{
int i;
for (i = 0; i < count; ++i)
{
printf("%d. person:\tname: %s, age: %d, job: %s\n", i + 1, iterator[i]->name, iterator[i]->age, iterator[i]->job);
}
}
void grow()
{
int i;
size += 5;
iterator = realloc(iterator, size);
if (iterator == NULL)
{
/*fprintf(stderr, "Memory allocation did not succeed\n");*/
exit(1);
}
printf("realloced to bigger\n");
for (i = size - 5; i < size; ++i)
{
iterator[i] = malloc(sizeof(person_t));
if (iterator[i] == NULL)
{
/*fprintf(stderr, "Memory allocation did not succeed\n");*/
exit(1);
}
}
}
void del()
{
char toDelete[30];
int i;
int toDeleteIndex;
scanf("%s", toDelete);
if ((strlen(toDelete) + 1) > 30)
{
do
{
fprintf(stderr, "Maximum 30 characters are allowed\n");
scanf("%s", toDelete);
} while ((strlen(toDelete) + 1) > 30);
}
for (i = 0; i < count; ++i)
{
if (strcmp(iterator[i]->name, toDelete) == 0)
{
toDeleteIndex = i;
}
}
if (i == count)
{
fprintf(stderr, "No match\nBack to menu\n");
}
else
{
free(iterator[toDeleteIndex]);
for (i = toDeleteIndex; i < count - 1; ++i)
{
iterator[i] = iterator[i + 1];
}
free(iterator[count]);
count--;
if (count == size - 6)
{
size -= 5;
iterator = realloc(iterator, size);
if (iterator == NULL)
{
/*fprintf(stderr, "Memory allocation did not succeed\n");*/
exit(1);
}
printf("realloced to smaller\n");
}
}
}
【问题讨论】:
标签: c pointers struct memory-management realloc