检测到堆损坏:在正常块之后(#87)
HEAP CORRUPTION DETECTED: after normal block(#87)
我正在尝试做一个从用户那里获取姓名数量的程序,然后它从用户那里获取姓名并将它们保存在字符串数组中。之后,它按 abc 对数组中的名称进行排序,然后打印排序的名称。该程序运行良好,但问题是当我尝试释放我定义的动态内存时。
这是代码:
#include <stdio.h>
#include <string.h>
#define STR_LEN 51
void myFgets(char str[], int n);
void sortString(char** arr, int numberOfStrings);
int main(void)
{
int i = 0, numberOfFriends = 0, sizeOfMemory = 0;
char name[STR_LEN] = { 0 };
char** arrOfNames = (char*)malloc(sizeof(int) * sizeOfMemory);
printf("Enter number of friends: ");
scanf("%d", &numberOfFriends);
getchar();
for (i = 0; i < numberOfFriends; i++) // In this loop we save the names into the array.
{
printf("Enter name of friend %d: ", i + 1);
myFgets(name, STR_LEN); // Get the name from the user.
sizeOfMemory += 1;
arrOfNames = (char*)realloc(arrOfNames, sizeof(int) * sizeOfMemory); // Change the size of the memory to more place to pointer from the last time.
arrOfNames[i] = (char*)malloc(sizeof(char) * strlen(name) + 1); // Set dynamic size to the name.
*(arrOfNames[i]) = '[=10=]'; // We remove the string in the currnet name.
strncat(arrOfNames[i], name, strlen(name) + 1); // Then, we save the name of the user into the string.
}
sortString(arrOfNames, numberOfFriends); // We use this function to sort the array.
for (i = 0; i < numberOfFriends; i++)
{
printf("Friend %d: %s\n", i + 1, arrOfNames[i]);
}
for (i = 0; i < numberOfFriends; i++)
{
free(arrOfNames[i]);
}
free(arrOfNames);
getchar();
return 0;
}
/*
Function will perform the fgets command and also remove the newline
that might be at the end of the string - a known issue with fgets.
input: the buffer to read into, the number of chars to read
*/
void myFgets(char str[], int n)
{
fgets(str, n, stdin);
str[strcspn(str, "\n")] = 0;
}
/*In this function we get array of strings and sort the array by abc.
Input: The array and the long.
Output: None*/
void sortString(char** arr, int numberOfStrings)
{
int i = 0, x = 0;
char tmp[STR_LEN] = { 0 };
for (i = 0; i < numberOfStrings; i++) // In this loop we run on all the indexes of the array. From the first string to the last.
{
for (x = i + 1; x < numberOfStrings; x++) // In this loop we run on the next indexes and check if is there smaller string than the currnet.
{
if (strcmp(arr[i], arr[x]) > 0) // If the original string is bigger than the currnet string.
{
strncat(tmp, arr[i], strlen(arr[i])); // Save the original string to temp string.
// Switch between the orginal to the smaller string.
arr[i][0] = '[=10=]';
strncat(arr[i], arr[x], strlen(arr[x]));
arr[x][0] = '[=10=]';
strncat(arr[x], tmp, strlen(tmp));
tmp[0] = '[=10=]';
}
}
}
}
打印名称后,当我想释放名称和数组时,在第一次尝试释放时,我收到错误消息:“检测到堆损坏:在正常块之后(#87)”。顺便说一句,只有当我输入 4 个或更多玩家时,我才会收到此错误。如果我输入 3 个或更少的玩家,程序将正常运行。
为什么会发生这种情况以及我应该如何解决它?
首先删除 malloc
和 realloc
的 return 值的不必要的(部分错误的)转换。 换句话说:将(char*)malloc(...
替换为malloc(...
,realloc
也是如此。
那么这里有一个大问题:realloc(arrOfNames, sizeof(int) * sizeOfMemory)
:你想分配一个pointers数组而不是int[=51数组=] 并且指针的大小可能与 int 的大小相同,也可能不同。您需要 sizeof(char**)
或更不易出错的 sizeof(*arrOfNames)
此处。
此外,这太复杂了(但实际上并没有错):
*(arrOfNames[i]) = '[=10=]';
strncat(arrOfNames[i], name, strlen(name) + 1);
相反,你可以简单地使用这个:
strcpy(arrOfNames[i], name);
sort
函数中的相同内容。
保持代码简单。
但其实你的sort
功能还有更多的问题。你天真地交换了字符串的 contents(顺便说一下,这是低效的),但真正的问题是如果你复制一个较长的字符串,比如 "Walter"
到一个较短的,比如 "Joe"
,您将超出为 "Joe"
.
分配的内存的末尾
不是交换字符串的内容,而是交换指针。
我建议你拿一支铅笔和一张纸,画出指针和它们所指向的内存。
我正在尝试做一个从用户那里获取姓名数量的程序,然后它从用户那里获取姓名并将它们保存在字符串数组中。之后,它按 abc 对数组中的名称进行排序,然后打印排序的名称。该程序运行良好,但问题是当我尝试释放我定义的动态内存时。 这是代码:
#include <stdio.h>
#include <string.h>
#define STR_LEN 51
void myFgets(char str[], int n);
void sortString(char** arr, int numberOfStrings);
int main(void)
{
int i = 0, numberOfFriends = 0, sizeOfMemory = 0;
char name[STR_LEN] = { 0 };
char** arrOfNames = (char*)malloc(sizeof(int) * sizeOfMemory);
printf("Enter number of friends: ");
scanf("%d", &numberOfFriends);
getchar();
for (i = 0; i < numberOfFriends; i++) // In this loop we save the names into the array.
{
printf("Enter name of friend %d: ", i + 1);
myFgets(name, STR_LEN); // Get the name from the user.
sizeOfMemory += 1;
arrOfNames = (char*)realloc(arrOfNames, sizeof(int) * sizeOfMemory); // Change the size of the memory to more place to pointer from the last time.
arrOfNames[i] = (char*)malloc(sizeof(char) * strlen(name) + 1); // Set dynamic size to the name.
*(arrOfNames[i]) = '[=10=]'; // We remove the string in the currnet name.
strncat(arrOfNames[i], name, strlen(name) + 1); // Then, we save the name of the user into the string.
}
sortString(arrOfNames, numberOfFriends); // We use this function to sort the array.
for (i = 0; i < numberOfFriends; i++)
{
printf("Friend %d: %s\n", i + 1, arrOfNames[i]);
}
for (i = 0; i < numberOfFriends; i++)
{
free(arrOfNames[i]);
}
free(arrOfNames);
getchar();
return 0;
}
/*
Function will perform the fgets command and also remove the newline
that might be at the end of the string - a known issue with fgets.
input: the buffer to read into, the number of chars to read
*/
void myFgets(char str[], int n)
{
fgets(str, n, stdin);
str[strcspn(str, "\n")] = 0;
}
/*In this function we get array of strings and sort the array by abc.
Input: The array and the long.
Output: None*/
void sortString(char** arr, int numberOfStrings)
{
int i = 0, x = 0;
char tmp[STR_LEN] = { 0 };
for (i = 0; i < numberOfStrings; i++) // In this loop we run on all the indexes of the array. From the first string to the last.
{
for (x = i + 1; x < numberOfStrings; x++) // In this loop we run on the next indexes and check if is there smaller string than the currnet.
{
if (strcmp(arr[i], arr[x]) > 0) // If the original string is bigger than the currnet string.
{
strncat(tmp, arr[i], strlen(arr[i])); // Save the original string to temp string.
// Switch between the orginal to the smaller string.
arr[i][0] = '[=10=]';
strncat(arr[i], arr[x], strlen(arr[x]));
arr[x][0] = '[=10=]';
strncat(arr[x], tmp, strlen(tmp));
tmp[0] = '[=10=]';
}
}
}
}
打印名称后,当我想释放名称和数组时,在第一次尝试释放时,我收到错误消息:“检测到堆损坏:在正常块之后(#87)”。顺便说一句,只有当我输入 4 个或更多玩家时,我才会收到此错误。如果我输入 3 个或更少的玩家,程序将正常运行。 为什么会发生这种情况以及我应该如何解决它?
首先删除 malloc
和 realloc
的 return 值的不必要的(部分错误的)转换。 换句话说:将(char*)malloc(...
替换为malloc(...
,realloc
也是如此。
那么这里有一个大问题:realloc(arrOfNames, sizeof(int) * sizeOfMemory)
:你想分配一个pointers数组而不是int[=51数组=] 并且指针的大小可能与 int 的大小相同,也可能不同。您需要 sizeof(char**)
或更不易出错的 sizeof(*arrOfNames)
此处。
此外,这太复杂了(但实际上并没有错):
*(arrOfNames[i]) = '[=10=]';
strncat(arrOfNames[i], name, strlen(name) + 1);
相反,你可以简单地使用这个:
strcpy(arrOfNames[i], name);
sort
函数中的相同内容。
保持代码简单。
但其实你的sort
功能还有更多的问题。你天真地交换了字符串的 contents(顺便说一下,这是低效的),但真正的问题是如果你复制一个较长的字符串,比如 "Walter"
到一个较短的,比如 "Joe"
,您将超出为 "Joe"
.
不是交换字符串的内容,而是交换指针。
我建议你拿一支铅笔和一张纸,画出指针和它们所指向的内存。