刻BITTER 2015-07-01 17:11 采纳率: 100%
浏览 2150
已采纳

C程序内存不能为read错误,包含文件和内存操作

各个方法每个都没问题,放一块儿就冒出个不明原因的错误

#include <stdio.h>
#include <math.h>
#include <time.h>

//get time difference
//days from 2015/6/9 to here.
int getTD();
//free()!
char* getTextFileContent(char*);
long getFileSize(FILE*);
//free()!
char* mStrCat(char*, char*);

int main()
{
    int TD = getTD() + 1;

    char buf[100];
    getcwd(buf, 100);

    char *listPath = mStrCat(buf, "\\plan.txt");
    //DEBUG
    printf("%s\r\n", listPath);

    char* text = getTextFileContent(listPath);
    free(listPath);
    printf("%s", text);
    text = (text == NULL) ? "" : text;

    system("cls");
    printf("高考后第[ %d ]天\r\n", TD);
    printf("Tasks:\r\n %s\r\n", text);
    system("pause & exit");

    free(text);

    return 0;
}

int getTD()
{
    struct tm tmptm = {0, 0, 0, 9, 5, 2015 - 1900};
    long startT = mktime(&tmptm);
    long nowT = time(NULL);
    //seconds
    long TDs = nowT - startT;
    //days
    double TDd = (double)TDs;
    TDd = TDd / (60 * 60 * 24);
    TDd = floor(TDd);
    return (int)TDd;
}

char* getTextFileContent(char *path)
{
    FILE *fp = fopen(path, "r");
    if(fp == NULL) 
        return NULL;
    long size = getFileSize(fp);
    int chLen = sizeof('\0');
    char *ptr = (char*)malloc(size + chLen);
    //block 作为这块内存区的起始指针将被作为字符串指针返回,ptr 经过运算后将指向内存区结尾。
    char *block = ptr;
    if(ptr == NULL)
    {
        return NULL;
    }

    int c;
    char ch;
    //依次将fgetc 获得的字符填入内存区。
    while((c = fgetc(fp)) != EOF)
    {
        ch = (char) c;
        memcpy(ptr, &ch, chLen);
        //移动ptr 到下一个待填入的地址。
        (int)ptr += chLen;
    }
    char endC = '\0';
    memcpy(ptr, &endC, chLen);

    return block;   
}

long getFileSize(FILE* f)
{
    long size = (fseek(f, 0L, SEEK_END) != 0) ? (ftell(f)) : -1;
    rewind(f);

    return size;
}

char* mStrCat(char *str1, char *str2)
{
    int str1Len = strlen(str1) + 1;
    int str2Len = strlen(str2) + 1;
    int byteNum = (str1Len + str2Len - 1) * sizeof(char);
    char *block = (char*)(malloc(byteNum));
    if(block == NULL)
        return NULL;

    memmove(block, str1, str1Len * sizeof(char));
    strcat(block, str2);

    return block;
}

文件内容可以正常输出,说明文件读取的部分大概没问题,mStrCat 经测试也没发现问题,但程序死活执行不到 system("cls") ,一到这儿Windows就会弹窗提示。
图片说明

文件内容可以正常输出:
图片说明

另外,运行程序的时候360报毒了,一个QVM。。。,然后运行几次之后那个cmd窗口无法关闭了(点什么都没反映,但光标在闪)。打开的任务管理器也变成了这样:
图片说明
自然,没能杀掉cmd,最后连资源管理器都不正常了,通过重启解决。(一个小练习而已杀伤力没这么大吧)

P.S. 通过TCC 编译


改动后的getTextFileContent 代码:(实际上没什么改动,但至少能用了)

 char* getTextFileContent(char *path)
{
    FILE *fp = fopen(path, "r");
    if(fp == NULL) 
        return NULL;

    long size = getFileSize(fp);

    int chLen = sizeof(char);
    char *ptr = (char*)malloc(size + chLen);
    char *block = ptr;
    if(ptr == NULL)
    {
        return NULL;
    }

    int c;
    char ch;
    while((c = fgetc(fp)) != EOF)
    {
        ch = (char)c;
        memcpy(ptr, &ch, chLen);
        ptr += chLen;
    }
    ch = '\0';
    memcpy(ptr, &ch, chLen);

    fclose(fp);
    return block;
}

文件大小为275b 时读取汉字都没问题(I don't know why ...),但到1.27k(全英文)时就又冒出了内存不能为written 错误,一瞬间想到当初在Android 上写的个文件复制程序会不时的冒出Segmentation Fault……

哪位大神来搭救一下!

  • 写回答

9条回答 默认 最新

  • 天已青色等烟雨来 2015-07-06 07:46
    关注

    有两处严重的错误:
    @1:text = (text == NULL) ? "" : text; 如果text为null,text会指向一个字符串常量,释放时候必崩溃
    @2:long size = (fseek(f, 0L, SEEK_END) != 0) ? (ftell(f)) : -1; 此处逻辑错误,long size = (fseek(f, 0L, SEEK_END) == 0) ? (ftell(f)) : -1;才正确

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(8条)

报告相同问题?

悬赏问题

  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化
  • ¥15 Mirare PLUS 进行密钥认证?(详解)
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥20 想用ollama做一个自己的AI数据库
  • ¥15 关于qualoth编辑及缝合服装领子的问题解决方案探寻
  • ¥15 请问怎么才能复现这样的图呀