qq_37936672 2021-06-11 09:21 采纳率: 0%
浏览 13

解析十六进行为字符串时出现free(): invalid next size (fast) 内存错误

代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef unsigned char uint8_t;
typedef unsigned short uint16_t;

typedef struct testmessage
{
    int station;
    char *barcodesn;
} Test_Message;

/**
 * @brief 将一个 string 类型的数据从接收缓冲区中解析出来
 * 
 * @param iRecvBuf 接收缓冲区
 * @param strlen 接收缓冲区长度
 * @param iPrintFlag 是否需要将接收到的数据打印出来
 * @return 返回解析结果
 */
char *HexToStr(uint8_t *iRecvBuf, uint8_t stringlen, uint8_t iRecvIndex, uint8_t iPrintFlag)
{
    uint16_t i = 0;
    char *iStr;

    iStr = (char *)malloc(sizeof(char) * stringlen);
    for (i = 0; i < stringlen; i++)
    {
        *(iStr + i) = *(iRecvBuf + i + 1 + iRecvIndex); //将iRecvBuf第位开始保存给结果字符串
    }
    iStr[stringlen] = '\0'; //在字符串的最后增加换行符
    if (iPrintFlag)
        printf("iStr:%s\n", iStr);

    return iStr;
}

/**
 * @brief 解析穴位与条码,并对应的出存在结构体中,返回结构体
 * 
 * @param iRecvBuf 接收缓冲区
 * @param iStrbuf 解析字符接收缓冲区
 * @param iPrintFlag 是否需要将接收到的数据打印出来
 * @return 返回解析结果,调用该函数后需要对内存进行释放,并对iStrbuf进行释放
 */
Test_Message *GetCsvName(uint8_t *iRecvBuf, char *iStrbuf, uint8_t iPrintFlag)
{
    uint8_t i;
    Test_Message *iStr;
    // char *iStrbuf;
    uint8_t stringlen, iRecvIndex;

    iStr = (Test_Message *)malloc(sizeof(Test_Message *) * strlen(iRecvBuf) * 4);
    iStr -> barcodesn = (char *)malloc(sizeof(char *) * strlen(iRecvBuf) * 4);

    for (i = 0; i < iRecvBuf[0]; i++)
    {
        switch (i)
        {
            case 0:
                stringlen = iRecvBuf[iRecvBuf[0] + 4];
                iRecvIndex = iRecvBuf[0] + 4;
                break;
            case 1:
                stringlen = iRecvBuf[iRecvBuf[0] + 4 + 1 + iRecvBuf[iRecvBuf[0] + 4]];
                iRecvIndex = iRecvBuf[0] + 4 + 1 + iRecvBuf[iRecvBuf[0] + 4];
                break;
            case 2:
                stringlen = iRecvBuf[iRecvBuf[0] + 4 + 1    
                    + iRecvBuf[iRecvBuf[0] + 4] +1                         
                    + iRecvBuf[iRecvBuf[0] + 4 + 1                   
                    + iRecvBuf[iRecvBuf[0] + 4]]];
                iRecvIndex = iRecvBuf[0] + 4 + 1 + iRecvBuf[iRecvBuf[0] + 4] + 1 + iRecvBuf[iRecvBuf[0] + 4 + 1 + iRecvBuf[iRecvBuf[0] + 4]];
                break;
            case 3:
                stringlen = iRecvBuf[iRecvBuf[0] + 4 + 1 + iRecvBuf[iRecvBuf[0] + 4] + 1 + iRecvBuf[iRecvBuf[0] + 4 + 1 + iRecvBuf[iRecvBuf[0] + 4]] + 1 + iRecvBuf[iRecvBuf[0] + 4 + 1   
                    + iRecvBuf[iRecvBuf[0] + 4] + 1                         
                    + iRecvBuf[iRecvBuf[0] + 4 + 1                   
                    + iRecvBuf[iRecvBuf[0] + 4]]]];
                iRecvIndex = iRecvBuf[0] + 4 + 1 + iRecvBuf[iRecvBuf[0] + 4] + 1 + iRecvBuf[iRecvBuf[0] + 4 + 1 + iRecvBuf[iRecvBuf[0] + 4]] + 1 + iRecvBuf[iRecvBuf[0] + 4 + 1    
                    + iRecvBuf[iRecvBuf[0] + 4] + 1                         
                    + iRecvBuf[iRecvBuf[0] + 4 + 1                   
                    + iRecvBuf[iRecvBuf[0] + 4]]];
                break;
            default:
                break;
        }
       
        if (iPrintFlag)
        printf("i:%d stringlen:%d iRecvIndex:%d\n", i, stringlen, iRecvIndex);
        iStrbuf = HexToStr(iRecvBuf, stringlen, iRecvIndex, iPrintFlag);
        
        iStr[i].station = iRecvBuf[i + 2];
        iStr[i].barcodesn =  iStrbuf;
        iStr[i].barcodesn[strlen(iStrbuf)] ='\0';

        if (iPrintFlag)
        printf("iStr[%d].station = %d iStr[%d].barcodesn:%s\n", i, iStr[i].station, i, iStr[i].barcodesn);
    }

    return iStr;
}

int main()
{
    uint8_t str[] = {
        4, 0, 1, 2, 3, 4, 4, 0, 64, 49, 95, 51, 56, 51, 52, 57, 97, 56, 56, 45, 98, 101, 101, 48, 45, 52, 99, 56, 99, 45, 57, 48, 50, 100, 45, 98, 100, 49, 99, 55, 50, 54, 99, 50, 98, 55, 52, 95, 50, 48, 50, 49, 45, 48, 54, 45, 48, 56, 32, 49, 56, 46, 50, 50, 46, 49, 53, 46, 48, 55, 54, 95, 48, 64, 50, 95, 48, 101, 56, 56, 100, 57, 49, 97, 45, 52, 53, 99, 50, 45, 52, 99, 57, 101, 45, 57, 101, 97, 52, 45, 53, 101, 57, 49, 57, 97, 54, 97, 50, 52, 97, 97, 95, 50, 48, 50, 49, 45, 48, 54, 45, 48, 56, 32, 49, 56, 46, 50, 50, 46, 49, 53, 46, 48, 55, 54, 95, 48, 64, 51, 95, 54, 57, 55, 99, 49, 101, 97, 55, 45, 57, 49, 57, 98, 45, 52, 51, 48, 102, 45, 98, 48, 101, 50, 45, 57, 101, 56, 53, 102, 56, 101, 101, 54, 57, 51, 52, 95, 50, 48, 50, 49, 45, 48, 54, 45, 48, 56, 32, 49, 56, 46, 50, 50, 46, 49, 53, 46, 48, 55, 54, 95, 48, 64, 52, 95, 55, 97, 48, 98, 99, 57, 48, 102, 45, 101, 99, 48, 102, 45, 52, 50, 97, 99, 45, 57, 97, 102, 54, 45, 100, 97, 54, 100, 98, 48, 48, 48, 51, 102, 54, 97, 95, 50, 48, 50, 49, 45, 48, 54, 45, 48, 56, 32, 49, 56, 46, 50, 50, 46, 49, 53, 46, 48, 55, 54, 95, 48,
    };

    Test_Message *str1;
    int i,j = 3;
    char *iStrbuf;

    while(j--)
    {
        str1 = GetCsvName(str, iStrbuf, 1);
        printf("\n");

        for(i = 0; i < 4; i++)
        {
        printf("%d, %s\n", str1[i].station, str1[i].barcodesn); 
        }
        
        free(iStrbuf);
        free(str1);
        free(str1->barcodesn);
        
    }

    return 0;
}

运行错误:

```c

pi@raspberrypi:~/Desktop/test/c $ gcc -o test1 test1.c
pi@raspberrypi:~/Desktop/test/c $ ./test1
i:0 stringlen:64 iRecvIndex:8
iStr:1_38349a88-bee0-4c8c-902d-bd1c726c2b74_2021-06-08 18.22.15.076_0
iStr[0].station = 1 iStr[0].barcodesn:1_38349a88-bee0-4c8c-902d-bd1c726c2b74_2021-06-08 18.22.15.076_0
i:1 stringlen:64 iRecvIndex:73
iStr:2_0e88d91a-45c2-4c9e-9ea4-5e919a6a24aa_2021-06-08 18.22.15.076_0
iStr[1].station = 2 iStr[1].barcodesn:2_0e88d91a-45c2-4c9e-9ea4-5e919a6a24aa_2021-06-08 18.22.15.076_0
i:2 stringlen:64 iRecvIndex:138
iStr:3_697c1ea7-919b-430f-b0e2-9e85f8ee6934_2021-06-08 18.22.15.076_0
iStr[2].station = 3 iStr[2].barcodesn:3_697c1ea7-919b-430f-b0e2-9e85f8ee6934_2021-06-08 18.22.15.076_0
i:3 stringlen:64 iRecvIndex:203
iStr:4_7a0bc90f-ec0f-42ac-9af6-da6db0003f6a_2021-06-08 18.22.15.076_0
iStr[3].station = 4 iStr[3].barcodesn:4_7a0bc90f-ec0f-42ac-9af6-da6db0003f6a_2021-06-08 18.22.15.076_0

1, 1_38349a88-bee0-4c8c-902d-bd1c726c2b74_2021-06-08 18.22.15.076_0
2, 2_0e88d91a-45c2-4c9e-9ea4-5e919a6a24aa_2021-06-08 18.22.15.076_0
3, 3_697c1ea7-919b-430f-b0e2-9e85f8ee6934_2021-06-08 18.22.15.076_0
4, 4_7a0bc90f-ec0f-42ac-9af6-da6db0003f6a_2021-06-08 18.22.15.076_0
i:0 stringlen:64 iRecvIndex:8
iStr:1_38349a88-bee0-4c8c-902d-bd1c726c2b74_2021-06-08 18.22.15.076_0
iStr[0].station = 1 iStr[0].barcodesn:1_38349a88-bee0-4c8c-902d-bd1c726c2b74_2021-06-08 18.22.15.076_0
i:1 stringlen:64 iRecvIndex:73
iStr:2_0e88d91a-45c2-4c9e-9ea4-5e919a6a24aa_2021-06-08 18.22.15.076_0
iStr[1].station = 2 iStr[1].barcodesn:2_0e88d91a-45c2-4c9e-9ea4-5e919a6a24aa_2021-06-08 18.22.15.076_0
i:2 stringlen:64 iRecvIndex:138
iStr:3_697c1ea7-919b-430f-b0e2-9e85f8ee6934_2021-06-08 18.22.15.076_0
iStr[2].station = 3 iStr[2].barcodesn:3_697c1ea7-919b-430f-b0e2-9e85f8ee6934_2021-06-08 18.22.15.076_0
i:3 stringlen:64 iRecvIndex:203
iStr:4_7a0bc90f-ec0f-42ac-9af6-da6db0003f6a_2021-06-08 18.22.15.076_0
iStr[3].station = 4 iStr[3].barcodesn:4_7a0bc90f-ec0f-42ac-9af6-da6db0003f6a_2021-06-08 18.22.15.076_0

1, 1_38349a88-bee0-4c8c-902d-bd1c726c2b74_2021-06-08 18.22.15.076_0
2, 2_0e88d91a-45c2-4c9e-9ea4-5e919a6a24aa_2021-06-08 18.22.15.076_0
3, 3_697c1ea7-919b-430f-b0e2-9e85f8ee6934_2021-06-08 18.22.15.076_0
4, 4_7a0bc90f-ec0f-42ac-9af6-da6db0003f6a_2021-06-08 18.22.15.076_0
free(): invalid next size (fast)
已放弃

```

  • 写回答

1条回答 默认 最新

  • 小P聊技术 2021-06-11 10:06
    关注

    在项目开发中,调试发现:
    free(): invalid next size (fast): 0x0000000001bd2e10 ***
    错误类型为内存泄露错误。
    后经查阅内存泄露得知导致内存泄露的原因可能有以下几种:
    (1)free了没有分配的内存

    (2)分配了内存忘记释放也有可能会出现这样的问题。

    (3)数组循环的时候越界了 ,写到了其他的内存里面, 然后free那个区域就会出现这样的问题。
    经核实我的问题不属于以上三种情况,源代码如下:

    FILE *fp = fopen(strcat(data_path,RECORD_FILE), "a");
    
    • 1

    问题出现在使用strcat()字符串拼接函数的方式上。
    C库函数-strcat()

    描述: char *strcat(char *dest, const char *src) 把 src 所指向的字符串追加到 dest 所指向的字符串的结尾。

    参数说明:

    • dest – 指向目标数组,该数组包含了一个 C 字符串,且足够容纳追加后的字符串。
    • src – 指向要追加的字符串,该字符串不会覆盖目标字符串。
      因为strcat()函数会将src所指向字符串追加到dest所指向字符串的末尾(覆盖掉dest末尾的‘\0’,拼接完最终只有一个‘\0’),所以dest必须要有足够的内存空间来容纳这两个字符串,否则会导致内存溢出错误,拼接成功后返回dest所指向的新字符串。
      解决方法:
        char *path=(char *)malloc(strlen(data_path)+strlen(RECORD_FILE));
        strcpy(path,data_path);
        strcat(path,RECORD_FILE);
    
        FILE *fp = fopen(path, "a");
        if (fp == NULL) {
              printf("Record file opening error!\n");
              return -1;
        }
        fputs(info, fp);
        fputc('\n', fp);
        fclose(fp);
        free(path);
    

    程序测试通过。

    评论

报告相同问题?

悬赏问题

  • ¥20 测距传感器数据手册i2c
  • ¥15 RPA正常跑,cmd输入cookies跑不出来
  • ¥15 求帮我调试一下freefem代码
  • ¥15 matlab代码解决,怎么运行
  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法