将char*复制到结构体触发EXC_BAD_ACCESS错误,求解决方法
修复窗口管理器原型中的EXC_BAD_ACCESS错误及函数指针问题
核心问题分析
你的代码触发EXC_BAD_ACCESS和函数指针赋值错误,主要有两个原因:
- 未初始化的title指针:
struct window里的title是char*类型,声明struct window w后,w.title是野指针,没有指向任何有效内存空间。strcpy尝试往这个非法地址写入数据,直接导致内存访问错误。 - 函数指针赋值错误:
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
相关产品推荐
相关产品推荐

