I am still new to C, so I have no idea what might be happening here.
In this implementation of a String
struct which should behave in a object-oriented way, there seems to be some error in the set
function as I get this diagnostic:
Process finished with exit code -1073741819 (0xC0000005)
This is my .h file:
#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);
This is its implementation:
#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 = =
str->compareTo = &compareTo;
str->concat = &concat;
str->freeString = &freeString;
str->set(str, value);
return str;
}
And this is my main.c:
#include <stdio.h>
#include "mystring.h"
int main()
{
String* string = newString("Hello");
printf("%s", string->value);
return 0;
}
When I run this code, I get the error which I provided above. But when I add a unrelated printf statement in "set" like so:
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);
}
This is the console output: DebugHello Process finished with exit code -1073741819 (0xC0000005)
Can anyone explain why?
There is at least a problem in the set
function:
free(self->value); // you free a pointer that has
self->length = strlen(value) + 1; // never been initialized
Freeing pointer that has never been initialized doesn't make sense and it results in undefined behaviour (most of the time some kind of crash).
You should initialize that pointer to NULL in newString
:
...
str->freeString = &freeString;
str->value = NULL; // <<< add this
str->set(str, value);
...
With that modification your code seems to work. I didn't investigate any further, so there might be more problems (bugs and/or design errors) elsewhere in this code.