微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

检测到堆损坏:在正常块之后#87

如何解决检测到堆损坏:在正常块之后#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]) = '\0';  // 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] = '\0';
                strncat(arr[i],arr[x],strlen(arr[x])); 
                arr[x][0] = '\0';
                strncat(arr[x],tmp,strlen(tmp));
                tmp[0] = '\0';
            }
        }
    }
}

打印名称后,当我想释放名称和数组时,在第一次尝试释放时,出现错误:“检测到堆损坏:正常块后(#87)”。顺便说一下,只有当我输入 4 个或更多玩家时才会出现此错误。如果我输入 3 个或更少的玩家,程序可以正常工作。 为什么会发生这种情况,我应该怎么做才能解决它?

解决方法

首先移除 mallocrealloc 的返回值的不必要的(部分错误的)转换。 换句话说:用(char*)malloc(...替换malloc(...realloc也一样。

那么这里有一个大问题:realloc(arrOfNames,sizeof(int) * sizeOfMemory):你想分配一个指针数组而不是一个int数组和一个指针的大小可能与 int 的大小相同,也可能不同。您需要 sizeof(char**) 或更不容易出错的 sizeof(*arrOfNames) 此处。

此外,这太复杂了(但实际上并没有错):

*(arrOfNames[i]) = '\0';
strncat(arrOfNames[i],name,strlen(name) + 1); 

相反,您可以简单地使用:

strcpy(arrOfNames[i],name);

sort 函数中的相同内容。

保持代码简单。


但实际上您的 sort 函数存在更多问题。你天真地交换了字符串的 contents(顺便说一句,这是低效的),但真正的问题是,如果你复制一个较长的字符串,比如 "Walter" 到一个较短的字符串,比如 { {1}},您将写入超出为 "Joe" 分配的内存的末尾。

不是交换字符串的内容,而是交换指针。

我建议你拿一支铅笔和一张纸,画出指针和它们指向的记忆。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?