You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

运行《Linux系统编程》read示例时报free(): invalid pointer错误如何解决?

问题解决与优化方案

free(): invalid pointer报错的根因非常明确:C标准规定free()必须传入malloc/calloc/realloc等内存分配函数返回的原始指针,你在循环中直接修改了buf指针本身的指向,若不复位到初始地址就调用free必然触发非法指针错误。你目前通过存储偏移复位指针的方案可正常运行,但存在两种更易维护、更低出错概率的优化方案:


方案1:使用临时遍历指针(最推荐)

原始buf指针全程保留初始分配地址不做修改,单独申请一个临时指针负责遍历读写位置,无需手动计算偏移、无需复位,从根源上避免遗漏指针复位的问题。
核心修改逻辑示例:

#include <stdio.h>
// 注意malloc.h是非标准头,替换为标准的stdlib.h
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

int main()
{
    int fd;
    if( (fd = open("someFile.txt", O_CREAT | O_WRONLY | O_TRUNC, 0664)) < 0) {
        perror("open for write");
        // 出错后直接终止,避免后续逻辑访问非法资源
        return 1;
    }
    char * text =  "This is an example text";
    write(fd, text, strlen(text));
    close(fd);

    if( (fd = open("someFile.txt", O_RDONLY)) < 0) {
        perror("open");
        return 1;
    }

    char *buf; 
    if( (buf = (char *) calloc(50, sizeof(char))) == NULL ) {
        perror("calloc");
        return 1;
    }
    // 单独定义临时遍历指针,不修改原始buf
    char *curr = buf;
    int len = 50;
    ssize_t ret;

    while (len != 0 && (ret = read (fd, curr, len)) != 0) {
        if (ret == -1) {
            if (errno == EINTR)
                continue;
            perror ("read");
            break;
        }
        len -= ret;
        curr += ret;
    }

    if( close(fd) == -1 )
        perror("close");

    // 原始buf指针始终未改动,直接释放即可
    free(buf);
    return 0;
}

方案2:使用数组下标访问

完全不修改指针本身,通过下标偏移计算读取位置,buf指针始终保持初始值:

int offset = 0;
while (len != 0 && (ret = read (fd, buf + offset, len)) != 0) {
    if (ret == -1) {
        if (errno == EINTR)
            continue;
        perror ("read");
        break;
    }
    len -= ret;
    offset += ret;
}
free(buf);

内容的提问来源于stack exchange,提问作者neolith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 07:45:01