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

将char*复制到结构体触发EXC_BAD_ACCESS错误,求解决方法

修复窗口管理器原型中的EXC_BAD_ACCESS错误及函数指针问题

核心问题分析

你的代码触发EXC_BAD_ACCESS和函数指针赋值错误,主要有两个原因:

  1. 未初始化的title指针:struct window里的title是char*类型,声明struct window w后,w.title是野指针,没有指向任何有效内存空间。strcpy尝试往这个非法地址写入数据,直接导致内存访问错误。
  2. 函数指针赋值错误:drawFunc是void (*)(struct window)类型的函数指针,但你写的w.drawFunc = draw(w);是直接调用了draw函数,把返回的void*类型值赋值给函数指针,类型不匹配,而且此时w的大部分成员还没初始化,调用draw(w)也没有意义。

修复方案

方案一:动态分配内存存储标题(推荐,适合需要修改标题的场景)

先通过malloc分配足够的内存给w.title,大小为标题字符串的长度加1(存储结束符\0),之后再用strcpy复制内容。使用完后记得用free释放内存,避免内存泄漏。

方案二:直接让title指向字符串字面量(适合标题不需要修改的场景)

字符串字面量本身存放在只读内存区,可以直接让w.title指向它,不需要strcpy,但要注意此时title应该声明为const char*,避免尝试修改只读内存导致错误。

修正函数指针赋值

直接将函数名draw赋值给drawFunc,因为函数名本身就是函数指针,不需要调用函数。

修正后的代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h> // 引入malloc/free所需头文件

struct window {
    char* title;
    int x;
    int y;
    int w;
    int h;
    void (*drawFunc)(struct window);
};

// 修正draw函数的返回值类型,匹配函数指针的void返回类型
void draw(struct window w) {
    printf("Window title: %s\n", w.title);
}

int main(int argc, const char* argv[]) {
    struct window w;
    const char* title = "hello"; // 字符串字面量默认带\0,不需要手动加

    // 方案一:动态分配内存
    w.title = malloc(strlen(title) + 1);
    if (w.title == NULL) { // 检查malloc是否成功
        fprintf(stderr, "Memory allocation failed\n");
        return 1;
    }
    strcpy(w.title, title);

    // 方案二:直接指向字符串字面量(注释掉方案一,打开下面这行即可)
    // w.title = (char*)title;

    // 正确赋值函数指针
    w.drawFunc = draw;

    // 初始化窗口其他属性
    w.x = 10;
    w.y = 10;
    w.w = 100;
    w.h = 200;

    // 调用绘制函数
    w.drawFunc(w);

    // 如果用了方案一,记得释放内存
    free(w.title);

    return 0;
}

额外说明

  • 使用malloc时一定要检查返回值是否为NULL,避免内存分配失败导致后续错误。
  • 如果标题不需要修改,优先用方案二,更简单高效,但要注意不要尝试修改w.title指向的内容,否则会触发只读内存访问错误。
  • 函数指针的赋值只需要函数名,不要加括号调用,加括号是执行函数并取返回值,和函数指针赋值完全是两回事。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 17:57:51