[英]Segmentation fault after realloc(). Can't assign allocated memory to pointer
[英]Can't reach memory allocated by realloc
我有一個指向結構( person_t
)的全局動態指針數組( iterator
)。 首先,我10*sizeof(person_t*)
memory 分配給iterator
,在內部我將sizeof(person_t)
memory 分配給每個iterator[i]
i = 0..9
。
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
以獲得更多 memory,但它似乎不起作用,盡管我沒有收到任何類型的警告或錯誤編譯(我使用gcc -ansi -pedantic -W -Wall -Wextra
編譯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");
}
}
}
就像在malloc
中一樣,您需要以字節為單位指定大小。 例如:
v = realloc(iterator, size * sizeof *iterator);
if( v != NULL ){
iterator = v;
}
這是一個常見錯誤,可能是選擇“size”以外的名稱的好理由。 (也許稱它為“容量”)。 請注意,盡管在您的代碼中可以執行iterator = realloc(iterator, size * sizeof *iterator)
,因為如果 realloc 返回 NULL,您會立即中止程序,但我修改了代碼以使用不同的變量只是為了強調該代碼模式未來的讀者。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.