C语言动态数组realloc导致Heap block错误信息
C Language Dynamic array realloc causes Heap block error message
我刚开始学习 C 编程并练习动态数组和 malloc 和 realloc。我正在使用 Visual Studio 并且代码在文件扩展名 .c 中
但我不知道为什么 realloc 会导致错误消息
"HEAP[Assignment1Start.exe]: Heap block at 01217FA8 modified at 01217FE8 past requested size of 38"
请按 ctrl-f 这句话“Here I want to realloc”
它会将您定向到导致错误消息的那一行。
#define _CRT_SECURE_NO_DEPRECATE
#include<stdio.h>
#define _CRT_SECURE_NO_WARNINGS
#define _NO_DEBUG_HEAP 1
int main()
{
FILE *ptr_file;
FILE *ptr_file2;
char buf[1000]; //1000 characters array. //if label[10] = "Single"; then label[2] outputs "n"// label[6] outputs "[=10=]" // label[7] outputs " " empty space
char *vArray2; //is as pointer to a character, to which you allocated memory to hold exactly 1 character.
int NoOfTasks = 0;
char **ArrayNo;
char **ArrayTemp;
//#define ArrayCapacity 15
int ArrayCapacity = 20;
#define ID_LEN 10
int i;
int power = 1;
int quitbtn = 8;
ptr_file = fopen("output.txt", "r");
if (!ptr_file)
return 1;
ArrayNo = (char*)malloc(ArrayCapacity*sizeof(char)); //allocate some memory that your pointer will point to. //You should always make it point to something or you can allocate some memory that your pointer will point to.
ArrayNo[NoOfTasks] = malloc((ID_LEN + 1) * sizeof(char));
strcpy(ArrayNo[NoOfTasks], "Quit\n");
NoOfTasks += 1;
while (fgets(buf, 1000, ptr_file) != NULL) //fgets adds the \n to the end of each line it reads and stores it in buf //outputs to command prompt//If the end-of-file (EOF) is reached the fgets function will return a NULL value
{
ArrayNo[NoOfTasks] = malloc((ID_LEN + 1) * sizeof(char));
strcpy(ArrayNo[NoOfTasks], buf);
NoOfTasks += 1;
}
while (power == 1){
for (int r = 0; r < NoOfTasks; r++){
printf("%d %s", r,ArrayNo[r]);
}
printf("\n Please enter the task order number");
int userInputInt1 = 0;
scanf("%d", &userInputInt1);
if (userInputInt1 != 0) //0 is quit NoOfTasks-1
{
printf("\n %s (1)Add task (2) Remove Task (3)Replace Task", ArrayNo[userInputInt1]);
int userInputInt2 = 0;
scanf("%d", &userInputInt2);
//int result = atoi(userInput2); // convert string to int
if (userInputInt2 == 3)
{
printf("\n Type in new task");
char userInput3[30];
scanf("%s", &userInput3);
if (userInput3 != " "){
int n;
printf("\n %s Replaced with %s \n", ArrayNo[userInputInt1], &userInput3);
strcpy(ArrayNo[userInputInt1], &userInput3);
strcat(ArrayNo[userInputInt1], "\n");
}
}
if (userInputInt2 == 2) //remove
{
int n;
NoOfTasks -= 1;
for (int c = userInputInt1; c < NoOfTasks; c++){
printf("\n %s Replaced with %s", ArrayNo[userInputInt1], ArrayNo[c + 1]);
ArrayNo[c] = ArrayNo[c + 1];
}
}
if (userInputInt2 == 1) //add
{
printf("\n Add a task");
char userInput4[30];
scanf("%s", &userInput4);
ArrayCapacity += 1;// increase ArrayCapacity by 1 because a new task is added
ArrayNo = (char**)realloc(ArrayNo, (ArrayCapacity* sizeof(char*))); // here I want to realloc memory for new element of the array ArrayNo when a new task is added
ArrayNo[NoOfTasks] = malloc((ID_LEN + 1) * sizeof(char));
strcpy(ArrayNo[NoOfTasks], &userInput4);
NoOfTasks += 1;
}
}
if (userInputInt1 == 0) //8 is quit NoOfTasks-1
{
ptr_file2 = fopen("WriteTo2.txt", "w");
if (!ptr_file2)
return 1;
for (int r = 1; r < NoOfTasks; r++){
fprintf(ptr_file2, "%s\n", ArrayNo[r]);
}
printf("\n You quit the program");
fclose(ptr_file2);
fclose(ptr_file);
power = 0;
}
}
getchar();
getchar();
getchar();
return 0;
}
初始分配不正确。
ArrayNo
是 char**
。而你
ArrayNo = (char*)malloc(ArrayCapacity*sizeof(char));
这仅分配 ArrayCapacity
个字节(sizeof(char)
为 1)。而数组实际上需要更多,ArrayCapacity*4
或 ArrayCapacity*8
字节(sizeof(char*)
是 4 或 8;假设它是 4,那么 ArrayNo[5] 从偏移量 4*5 开始,这已经是超出分配的区域)。所以,当你填充数组时,你会覆盖一些你不允许的内存字节,幸运的是 realloc
(在调试模式下)对此进行检查并在它注意到有内存损坏。
我刚开始学习 C 编程并练习动态数组和 malloc 和 realloc。我正在使用 Visual Studio 并且代码在文件扩展名 .c 中 但我不知道为什么 realloc 会导致错误消息 "HEAP[Assignment1Start.exe]: Heap block at 01217FA8 modified at 01217FE8 past requested size of 38" 请按 ctrl-f 这句话“Here I want to realloc” 它会将您定向到导致错误消息的那一行。
#define _CRT_SECURE_NO_DEPRECATE
#include<stdio.h>
#define _CRT_SECURE_NO_WARNINGS
#define _NO_DEBUG_HEAP 1
int main()
{
FILE *ptr_file;
FILE *ptr_file2;
char buf[1000]; //1000 characters array. //if label[10] = "Single"; then label[2] outputs "n"// label[6] outputs "[=10=]" // label[7] outputs " " empty space
char *vArray2; //is as pointer to a character, to which you allocated memory to hold exactly 1 character.
int NoOfTasks = 0;
char **ArrayNo;
char **ArrayTemp;
//#define ArrayCapacity 15
int ArrayCapacity = 20;
#define ID_LEN 10
int i;
int power = 1;
int quitbtn = 8;
ptr_file = fopen("output.txt", "r");
if (!ptr_file)
return 1;
ArrayNo = (char*)malloc(ArrayCapacity*sizeof(char)); //allocate some memory that your pointer will point to. //You should always make it point to something or you can allocate some memory that your pointer will point to.
ArrayNo[NoOfTasks] = malloc((ID_LEN + 1) * sizeof(char));
strcpy(ArrayNo[NoOfTasks], "Quit\n");
NoOfTasks += 1;
while (fgets(buf, 1000, ptr_file) != NULL) //fgets adds the \n to the end of each line it reads and stores it in buf //outputs to command prompt//If the end-of-file (EOF) is reached the fgets function will return a NULL value
{
ArrayNo[NoOfTasks] = malloc((ID_LEN + 1) * sizeof(char));
strcpy(ArrayNo[NoOfTasks], buf);
NoOfTasks += 1;
}
while (power == 1){
for (int r = 0; r < NoOfTasks; r++){
printf("%d %s", r,ArrayNo[r]);
}
printf("\n Please enter the task order number");
int userInputInt1 = 0;
scanf("%d", &userInputInt1);
if (userInputInt1 != 0) //0 is quit NoOfTasks-1
{
printf("\n %s (1)Add task (2) Remove Task (3)Replace Task", ArrayNo[userInputInt1]);
int userInputInt2 = 0;
scanf("%d", &userInputInt2);
//int result = atoi(userInput2); // convert string to int
if (userInputInt2 == 3)
{
printf("\n Type in new task");
char userInput3[30];
scanf("%s", &userInput3);
if (userInput3 != " "){
int n;
printf("\n %s Replaced with %s \n", ArrayNo[userInputInt1], &userInput3);
strcpy(ArrayNo[userInputInt1], &userInput3);
strcat(ArrayNo[userInputInt1], "\n");
}
}
if (userInputInt2 == 2) //remove
{
int n;
NoOfTasks -= 1;
for (int c = userInputInt1; c < NoOfTasks; c++){
printf("\n %s Replaced with %s", ArrayNo[userInputInt1], ArrayNo[c + 1]);
ArrayNo[c] = ArrayNo[c + 1];
}
}
if (userInputInt2 == 1) //add
{
printf("\n Add a task");
char userInput4[30];
scanf("%s", &userInput4);
ArrayCapacity += 1;// increase ArrayCapacity by 1 because a new task is added
ArrayNo = (char**)realloc(ArrayNo, (ArrayCapacity* sizeof(char*))); // here I want to realloc memory for new element of the array ArrayNo when a new task is added
ArrayNo[NoOfTasks] = malloc((ID_LEN + 1) * sizeof(char));
strcpy(ArrayNo[NoOfTasks], &userInput4);
NoOfTasks += 1;
}
}
if (userInputInt1 == 0) //8 is quit NoOfTasks-1
{
ptr_file2 = fopen("WriteTo2.txt", "w");
if (!ptr_file2)
return 1;
for (int r = 1; r < NoOfTasks; r++){
fprintf(ptr_file2, "%s\n", ArrayNo[r]);
}
printf("\n You quit the program");
fclose(ptr_file2);
fclose(ptr_file);
power = 0;
}
}
getchar();
getchar();
getchar();
return 0;
}
初始分配不正确。
ArrayNo
是 char**
。而你
ArrayNo = (char*)malloc(ArrayCapacity*sizeof(char));
这仅分配 ArrayCapacity
个字节(sizeof(char)
为 1)。而数组实际上需要更多,ArrayCapacity*4
或 ArrayCapacity*8
字节(sizeof(char*)
是 4 或 8;假设它是 4,那么 ArrayNo[5] 从偏移量 4*5 开始,这已经是超出分配的区域)。所以,当你填充数组时,你会覆盖一些你不允许的内存字节,幸运的是 realloc
(在调试模式下)对此进行检查并在它注意到有内存损坏。