首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C (glibc),realloc错误“损坏的大小与prev_size中止”

C (glibc),realloc错误“损坏的大小与prev_size中止”
EN

Stack Overflow用户
提问于 2022-01-06 22:01:48
回答 1查看 187关注 0票数 1

我读过一些关于这方面的帖子,但我是一个初学者,很难理解内存管理和调试过程。我觉得自己被困住了,不知道到哪里去找答案。我非常感谢任何帮助/指针来理解这个概念和解决bug的方法。FYI,我甚至还没有学会使用任何类型的调试控制台/程序。

在这段代码中,我的目标是创建一个函数,该函数可以在只读模式下打开具有给定名称的文本文件,并将char *返回到具有文件全部内容的内存地址。

这段代码运行时使用的是一个短的测试文件,但是在realloc函数的第12次运行时,始终存在“损坏的大小与prev_size中止”的错误。

下面是整个代码和输出,测试运行的短和长文本。

===码====

代码语言:javascript
复制
/////////////////////////////////////////////////////////////
/////                                                   /////
///// FILE I/O
///// Character Type, Read only mode 
///// Fixed Buffer Size by #define STR_BUFFER size
/////                                                   /////
/////////////////////////////////////////////////////////////
// USE: ./fopenRfixedsize argument
// Example: ./fopenRfixedsize filename
// Description: 
//  - argument is the filename
//  - only one argument allowed
// ,or char *fopenRfixedsize(char *fName[]);
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>


#ifndef STR_BUFFER
    #define STR_BUFFER 25000
#endif


FILE *fRead;


char *fopenRfixedsize(char *fName[]);


///////////////////////////////////////////////////////////////////////////////////////////////////
// temp main function for individual module testing
int main(int argc, char *argv[])
{
    if (argc != 2) // input limited to single file name only
    {
        printf("Usage: ./fopenRfixedsize filename\n");
        exit (1);
    }
    printf("%s", fopenRfixedsize(&argv[1]));
    return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////


// parent, sole primary function for fopenRfixedsize()
char *fopenRfixedsize(char *fName[])
{
    errno = 0; // initialize errno

    char *fContent = (char *) malloc (sizeof(char));
    fContent[0] = '\0';
    fRead = fopen(*fName, "r"); // open file
    if (fRead) // if fopen returned value other than 0, file open successful.
    {
        // create memory space to read file, fixed size #define STR_BUFFER 'size'
        char *sBuffer = (char *) malloc (STR_BUFFER * sizeof(char)); 
        if(sBuffer == 0)
        {
            printf("Memory allocation error (sBuffer): %d\n", errno);
            free(sBuffer);
            fclose(fRead);
            return "\0";
        }
        while(!feof(fRead)) // feof is not 0 == fRead is not at EOF (End of File)
        {
            // read file and store to the buffer,
            //  - until fRead points EOF or until string size reaches STR_BUFFER
            fgets(sBuffer, STR_BUFFER, fRead); 
            if (!feof(fRead)) // if feof == 0, fRead is at EOF (End of File)
            {
                //////////////////////////////////////////////////////////////////////////////////////////////////////
                // debug line, 1/3
                printf("==========================\n");
                printf("=== Beginning of Cycle ===\n");
                printf("==========================\n");
                printf("strlen(fContent): %d, strlen(sBuffer): %d\n", (int)strlen(fContent), (int)strlen(sBuffer));
                printf("fContent: %s", fContent);
                if (strlen(fContent) == 0) printf("\n");
                printf("sBuffer: %s", sBuffer);
                printf("\n");
                // debug line ends, 1/3
                //////////////////////////////////////////////////////////////////////////////////////////////////////

                fContent = (char *) realloc (fContent, (strlen(fContent) * sizeof(char) + strlen(sBuffer) * sizeof(char)));
                
                //////////////////////////////////////////////////////////////////////////////////////////////////////
                // debug line, 2/3
                printf("realloc with size %d successful\n", (int)(strlen(fContent) * sizeof(char) + strlen(sBuffer) * sizeof(char)));
                // debug line ends, 2/3
                //////////////////////////////////////////////////////////////////////////////////////////////////////

                if(fContent == 0)
                {
                    printf("Memory allocation error (fContent): %d\n", errno); 
                    free(fContent);
                    free(sBuffer);
                    fclose(fRead);
                    return "\0";
                }
                strcat(fContent, sBuffer);
                
                /////////////////////////////////////////////////////////////////////////////////////////////////////
                // debug line, 3/3
                printf("strcat(fContent, sBuffer) complete\n");
                printf("\n");
                printf("fContent: %s", fContent);
                printf("sBuffer: %s", sBuffer);
                printf("==========================\n");
                printf("===    End of Cycle    ===\n");
                printf("==========================\n");
                printf("\n");
                // debug line end, 3/3
                ////////////////////////////////////////////////////////////////////////////////////////////////////
            }
        }
        free(sBuffer);
    }
    else // of fopen returns 0, NULL pointer
    {
        printf("Cannot open the file ");
        printf("(Error Number: %d)\n", errno); // print errno message for debug
    }
    fclose(fRead); // close open files prior exiting program.
    return fContent;
}

===输出1,小尺寸文本文件===

代码语言:javascript
复制
./fopenRfixedsize ftest.txt

==========================
=== Beginning of Cycle ===
==========================
strlen(fContent): 0, strlen(sBuffer): 42
fContent: 
sBuffer: Really trying to get this thing work.....

realloc with size 42 successful
strcat(fContent, sBuffer) complete

fContent: Really trying to get this thing work.....
sBuffer: Really trying to get this thing work.....
==========================
===    End of Cycle    ===
==========================

==========================
=== Beginning of Cycle ===
==========================
strlen(fContent): 42, strlen(sBuffer): 42
fContent: Really trying to get this thing work.....
sBuffer: Why is this so hard for me .... grrr.....

realloc with size 84 successful
strcat(fContent, sBuffer) complete

fContent: Really trying to get this thing work.....
Why is this so hard for me .... grrr.....
sBuffer: Why is this so hard for me .... grrr.....
==========================
===    End of Cycle    ===
==========================

Really trying to get this thing work.....
Why is this so hard for me .... grrr.....

===输出2,大尺寸文本文件===

代码语言:javascript
复制
./fopenRfixedsize sorted5000.txt

==========================
=== Beginning of Cycle ===
==========================
strlen(fContent): 0, strlen(sBuffer): 2
fContent: 
sBuffer: 1

realloc with size 2 successful
strcat(fContent, sBuffer) complete

fContent: 1
sBuffer: 1
==========================
===    End of Cycle    ===
==========================

==========================
=== Beginning of Cycle ===
==========================
strlen(fContent): 2, strlen(sBuffer): 2
fContent: 1
sBuffer: 2

realloc with size 4 successful
strcat(fContent, sBuffer) complete

fContent: 1
2
sBuffer: 2
==========================
===    End of Cycle    ===
==========================

==========================
=== Beginning of Cycle ===
==========================
strlen(fContent): 4, strlen(sBuffer): 2
fContent: 1
2
sBuffer: 3

realloc with size 6 successful
strcat(fContent, sBuffer) complete

fContent: 1
2
3
sBuffer: 3
==========================
===    End of Cycle    ===
==========================

==========================
=== Beginning of Cycle ===
==========================
strlen(fContent): 6, strlen(sBuffer): 2
fContent: 1
2
3
sBuffer: 4

realloc with size 8 successful
strcat(fContent, sBuffer) complete

fContent: 1
2
3
4
sBuffer: 4
==========================
===    End of Cycle    ===
==========================

==========================
=== Beginning of Cycle ===
==========================
strlen(fContent): 8, strlen(sBuffer): 2
fContent: 1
2
3
4
sBuffer: 5

realloc with size 10 successful
strcat(fContent, sBuffer) complete

fContent: 1
2
3
4
5
sBuffer: 5
==========================
===    End of Cycle    ===
==========================

==========================
=== Beginning of Cycle ===
==========================
strlen(fContent): 10, strlen(sBuffer): 2
fContent: 1
2
3
4
5
sBuffer: 6

realloc with size 12 successful
strcat(fContent, sBuffer) complete

fContent: 1
2
3
4
5
6
sBuffer: 6
==========================
===    End of Cycle    ===
==========================

==========================
=== Beginning of Cycle ===
==========================
strlen(fContent): 12, strlen(sBuffer): 2
fContent: 1
2
3
4
5
6
sBuffer: 7

realloc with size 14 successful
strcat(fContent, sBuffer) complete

fContent: 1
2
3
4
5
6
7
sBuffer: 7
==========================
===    End of Cycle    ===
==========================

==========================
=== Beginning of Cycle ===
==========================
strlen(fContent): 14, strlen(sBuffer): 2
fContent: 1
2
3
4
5
6
7
sBuffer: 8

realloc with size 16 successful
strcat(fContent, sBuffer) complete

fContent: 1
2
3
4
5
6
7
8
sBuffer: 8
==========================
===    End of Cycle    ===
==========================

==========================
=== Beginning of Cycle ===
==========================
strlen(fContent): 16, strlen(sBuffer): 2
fContent: 1
2
3
4
5
6
7
8
sBuffer: 9

realloc with size 18 successful
strcat(fContent, sBuffer) complete

fContent: 1
2
3
4
5
6
7
8
9
sBuffer: 9
==========================
===    End of Cycle    ===
==========================

==========================
=== Beginning of Cycle ===
==========================
strlen(fContent): 18, strlen(sBuffer): 3
fContent: 1
2
3
4
5
6
7
8
9
sBuffer: 10

realloc with size 21 successful
strcat(fContent, sBuffer) complete

fContent: 1
2
3
4
5
6
7
8
9
10
sBuffer: 10
==========================
===    End of Cycle    ===
==========================

==========================
=== Beginning of Cycle ===
==========================
strlen(fContent): 21, strlen(sBuffer): 3
fContent: 1
2
3
4
5
6
7
8
9
10
sBuffer: 11

realloc with size 24 successful
strcat(fContent, sBuffer) complete

fContent: 1
2
3
4
5
6
7
8
9
10
11
sBuffer: 11
==========================
===    End of Cycle    ===
==========================

==========================
=== Beginning of Cycle ===
==========================
strlen(fContent): 24, strlen(sBuffer): 3
fContent: 1
2
3
4
5
6
7
8
9
10
11
sBuffer: 12

corrupted size vs. prev_size
Aborted

======

谢谢你抽出时间来看这件事,我期待着得到你的一些建议。

真心的。J.

EN

Stack Overflow用户

回答已采纳

发布于 2022-01-06 22:26:24

您没有为空终止符分配足够的空间:fContent = (char *) realloc (fContent, (strlen(fContent) * sizeof(char) + strlen(sBuffer) * sizeof(char)));应该读取:

代码语言:javascript
复制
fContent = realloc(fContent, strlen(fContent) + strlen(sBuffer) + 1);

此外,您应该将对fclose(fRead);的调用移到if块的末尾:正如编码的那样,如果打开文件失败,fclose(fRead)将有未定义的行为。

重新处理字符串文本"\0" (应该是"" )是有问题的,因为调用方需要对结果调用free()。您应该返回NULL以指示错误。

还读了Why is “while ( !feof (file) )” always wrong?

以下是修改后的版本:

代码语言:javascript
复制
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifndef STR_BUFFER
    #define STR_BUFFER 25000
#endif

char *fopenRfixedsize(const char *fName);

int main(int argc, char *argv[])
{
    if (argc != 2) // input limited to single file name only
    {
        printf("Usage: ./fopenRfixedsize filename\n");
        return 1;
    }
    printf("%s", fopenRfixedsize(argv[1]));
    return 0;
}

// parent, sole primary function for fopenRfixedsize()
char *fopenRfixedsize(const char *fName)
{
    FILE *fRead = fopen(fName, "r"); // open file
    if (fRead == NULL) {
        printf("Cannot open file %s: %s\n", fName, strerror(errno));
        return NULL;
    }
    // allocate memory space to read file, fixed size #define STR_BUFFER 'size'
    char *sBuffer = (char *)malloc(STR_BUFFER * sizeof(char)); 
    if (sBuffer == NULL) {
        printf("Memory allocation error (sBuffer): %s\n", strerror(errno));
        fclose(fRead);
        return NULL;
    }
    char *fContent = (char *)malloc(1);
    if (fContent == NULL) {
        printf("Memory allocation error (fContent): %s\n", strerror(errno));
        free(sBuffer);
        fclose(fRead);
        return NULL;
    }
    size_t len = 0;
    fContent[len] = '\0';

    while (fgets(sBuffer, STR_BUFFER, fRead)) {
       size_t len1 = strlen(sBuffer);
       fNewContent = (char *)realloc(fContent, len + len1 + 1);
       if (fNewContent == NULL) {
           printf("Memory reallocation error (fContent): %s\n", strerror(errno)); 
           free(fContent);
           free(sBuffer);
           fclose(fRead);
           return NULL;
       }
       fContent = fNewContent
       strcpy(fContent + len, sBuffer);
       len += len1;
    }
    free(sBuffer);
    fclose(fRead);
    return fContent;
}
票数 1
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70614151

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档