为什么我得到错误“Process finished with exit code -1073741819(0xC 0000005)in my code”,但如果我添加一个无关的print语句,它仍然有效?

uurv41yg  于 11个月前  发布在  其他
关注(0)|答案(2)|浏览(97)

我对C还是新手,所以我不知道这里会发生什么。
在这个String结构的实现中,应该以面向对象的方式运行,在set函数中似乎有一些错误,因为我得到了这个诊断:

Process finished with exit code -1073741819 (0xC0000005)

字符串
这是我的.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);


这是它的实现:

#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;
}


这是我的主菜单。

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

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

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

    return 0;
}


当我运行这段代码时,我得到了我上面提供的错误。但是当我在“set”中添加一个不相关的printf语句时,如下所示:

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

    printf("Debug");

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


这是控制台输出:gHello Process finished with exit code -1073741819(0xC 0000005)
有谁能解释一下原因吗?

vxbzzdmp

vxbzzdmp1#

set函数至少有一个问题:

free(self->value);                 //  you free a pointer that has 
  self->length = strlen(value) + 1;  //  never been initialized

字符串
释放从未初始化的指针是没有意义的,它会导致未定义的行为(大多数情况下是某种崩溃)。
您应该在newString中将该指针初始化为NULL:

...
  str->freeString = &freeString;
  str->value = NULL;  // <<< add this

  str->set(str, value);
  ...


我没有进一步调查,所以在这段代码的其他地方可能有更多的问题(bug和/或设计错误)。

ttcibm8c

ttcibm8c2#

OP标题:“...但如果我添加一个无关的print语句,它仍然有效?”和“* 有人能解释一下为什么吗?
printf()使用动态内存分配来实现其功能。
引入“
(不相关)print语句 ”会改变环境(可能是第一次在执行过程中使用动态分配)。因此,不工作的程序版本访问的任何字节都将被替换或重定向到其他字节,这些字节包含足够的NUL字符,可以解释为free(NULL),这是函数的一个完全合法的参数。
教训:当分配变量(特别是struct的)时,无论是在堆栈上还是在堆上,都要确保完全初始化变量。这看起来很浪费,但是这种做法可以让你保存几个小时来追踪行为不端程序中难以捉摸的bug(并在SO上发布问题)。
此外:malloc()可能会失败。养成编写代码检查这样的调用的返回值的习惯。假设一切都正常工作被称为“
在黑暗中吹口哨 *”。

相关问题