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

为何C语言代码报错0xC0000005,加无关printf却能部分运行?

问题:C语言面向对象String结构体运行时出现0xC0000005错误

刚接触C语言,我实现了一个面向对象风格的String结构体,运行时弹出错误:Process finished with exit code -1073741819 (0xC0000005),问题似乎出在set函数里。

在set函数中加了一条无关的printf("Debug")后,控制台能输出DebugHello,但还是会报同样的错误。


相关代码

头文件(mystring.h)

#include <string.h>
#include <stdbool.h>

typedef struct String_Struct
{
    char* value;
    unsigned int length;

    void (*set) (struct String_Struct* self, char* value);
    bool (*equals) (const struct String_Struct* self, const struct String_Struct* other);
    int (*compareTo) (const struct String_Struct* self, const struct String_Struct* other);
    void (*concat) (struct String_Struct* self, const struct String_Struct* other);
    void (*freeString) (struct String_Struct* self);
} String;

String* newString (char* value);
void set (String* self, char* value);
bool equals (const String* self, const String* other);
int compareTo (const String* self, const String* other);
void concat (String* self, const String* other);
void freeString (String* self);

实现文件(mystring.c)

#include "mystring.h"
#include <stdlib.h>
#include <stdio.h>

void set (String* self, char* value)
{
    // Only proceed if self and value exist
    if (!self || !value)
    {
        return;
    }

    free(self->value);
    self->length = strlen(value) + 1;
    self->value = (char*) malloc(sizeof(char) * self->length);
    strcpy(self->value, value);
}

int compareTo (const String* self, const String* other)
{
    if ((!self && other) || (self && !other))
        return INT_MIN;

    return strcmp(self->value, other->value);
}

bool equals (const String* self, const String* other)
{
    if ((!self && other) || (self && !other))
        return false;

    if (self == other)
        return true;

    return strcmp(self->value, other->value) == 0;
}

void concat (String* self, const String* other)
{
    if (!self || !other)
    {
        return;
    }

    char* result = (char*) malloc(sizeof(char) * (strlen(self->value) + strlen(other->value) + 2));

    strcpy(result, self->value);
    strcat(result, other->value);

    self->set(self, result);
}

void freeString (String* self)
{
    free(self->value);
    free(self);
}

String* newString (char* value)
{
    String* str = (String*) malloc(sizeof(String));

    str->set = &set;
    str->equals = &equals;
    str->compareTo = &compareTo;
    str->concat = &concat;
    str->freeString = &freeString;

    str->set(str, value);

    return str;
}

main.c

#include <stdio.h>
#include "mystring.h"

int main()
{
    String* string = newString("Hello");

    printf("%s", string->value);

    return 0;
}

错误原因与修复方案

核心错误:野指针非法free

在newString函数中,用malloc分配String结构体内存后,str->value是未初始化的野指针。第一次调用set函数时,free(self->value)相当于释放一块不属于你的内存,直接触发了0xC0000005内存访问违规错误。

加printf后能输出是因为内存布局巧合,野指针暂时没触发致命崩溃,但本质问题没解决。

修复步骤

  1. 初始化value为NULL
    在newString中分配结构体后,先把str->value设为NULL,标准C中free(NULL)是安全操作,不会触发错误:
String* newString (char* value)
{
    String* str = (String*) malloc(sizeof(String));

    str->value = NULL; // 关键:初始化空指针
    str->set = &set;
    str->equals = &equals;
    str->compareTo = &compareTo;
    str->concat = &concat;
    str->freeString = &freeString;

    str->set(str, value);

    return str;
}
  1. 修复concat中的内存泄漏
    concat里用malloc创建的result,在调用set后没有释放,会导致内存泄漏,需要手动free:
void concat (String* self, const String* other)
{
    if (!self || !other)
    {
        return;
    }

    char* result = (char*) malloc(sizeof(char) * (strlen(self->value) + strlen(other->value) + 2));

    strcpy(result, self->value);
    strcat(result, other->value);

    self->set(self, result);
    free(result); // 释放临时内存
}
  1. main函数中释放String对象
    程序结束前记得调用freeString释放内存,避免泄漏:
int main()
{
    String* string = newString("Hello");

    printf("%s", string->value);

    string->freeString(string); // 释放对象
    return 0;
}

额外注意点

  • compareTo中使用INT_MIN需要包含<limits.h>头文件,否则会编译报错;
  • C语言中malloc的返回值不需要强制转换(C++才需要),可以去掉(char*)这类转换让代码更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 04:25:41