Something Wrong With Linux or am I just dumb?

I don't understand why this program segfaults:

#include
#include
#include

typedef struct dString_struct{
int size;
char* data;
}dString;

void dString_init(dString** _string, int initSize){
dString* string = *_string;
string = (dString*) malloc(sizeof(dString));
string -> size = initSize;
string -> data = (char*) malloc(sizeof(char)*initSize);
}

void dString_delete(dString** _string){
dString* string = *_string;
free(string -> data);
free(string);
}

int main(){

dString* string;
/*
string = (dString*) malloc(sizeof(dString));
string -> size = 2;
string -> data = (char*) malloc(sizeof(char)*2);

free(string -> data);
free(string);*/

dString_init(&string, 2);
dString_delete(&string);
return 0;
}


The commented-out code does not segfault, btw.

Either I'm an idiot, or there is something seriously wrong with how free() works on Linux.

bump

pls help

string is defined in string.h, and you're using it as a variable name in both dString_init and dString_delete. I don't think it's causing the problem, but even if it somehow compiles and runs, it's exceedingly bad practice to use 'string' for a variable name.

Works fine on cpp.sh. Want me to reboot into Linux and try it?

Nevermind, apparently C's string.h does not directly define a string type. Still a bad idea to name variables 'string'.

The pointers got fucked up.
void dString_init(dString** _string, int initSize){
//dString* string = *_string;
(*_string) = (dString*) malloc(sizeof(dString));
(*_string) -> size = initSize;
(*_string) -> data = (char*) malloc(sizeof(char)*initSize);
}
.

Your pointer is the problem. Try to understand what variables and their addresses in C mean, especially when pointers are involved.
When you write dString* string; you create a new pointer variable. You didn't initialize it with anything so it points to something undefined.
You then pass the address of that variable into the init function. There you initialize a new pointer. But that is a new pointer variable. And you allocate memory from that pointer which is not the same as in your main function. So the pointer in your main function is still undefined.
And passing a null pointer to free results in a segfault.

Why even pass in dString** instead of just a dString*?

This is my new code taking your suggestions into account. It compiles but the string doesn't get printed out

#include
#include
#include

typedef struct dString_struct{
int size;
char* data;
}dString;

void dString_init(dString** _string, int initSize){
*_string = (dString*) malloc(sizeof(dString));
(*_string) -> size = initSize;
(*_string) -> data = (char*) malloc(sizeof(char)*initSize);
}

void dString_delete(dString** _string){
//free((*_string) -> data);
//free(*_string);
}

void dString_resize(dString** _string, int newSize){
dString* newString = NULL;
dString_init(&newString, newSize);
strcpy(newString -> data, (*_string) -> data);
dString_delete(_string);
*_string = newString;
}

void dString_write(dString** _string, char* input){
if (strlen(input) >= (*_string) -> size)
dString_resize(_string, strlen(input)*10);
else
strcpy((*_string) -> data, input);
}

void dString_print(dString** _string){
printf("%c", (*_string) -> data[0]);
}

int main(){

dString* string = NULL;
/*
string = (dString*) malloc(sizeof(dString));
string -> size = 2;
string -> data = (char*) malloc(sizeof(char)*2);

free(string -> data);
free(string);*/

char* newString = "randomStuff";

dString_init(&string, 2);
dString_write(&string, newString);
dString_print(&string);
dString_delete(&string);
return 0;
}

These:
Because otherwise the pointer in main will not be changed to whats allocated in dString_init.

In the main function there's a dString* variable.
If you want to write a separate function that modifies this variable you need to pass that variable as a pointer, hence dString**.

You don't write properly. The resize is triggered but you don't strcpy after the resize. Try

void dString_write(dString** _string, char* input){
if (strlen(input) >= (*_string) -> size)
dString_resize(_string, strlen(input)*10);
strcpy((*_string) -> data, input);
}

goddamit!

>printf("%c", (*_string) -> data[0]);
This should only print a single character, shouldn't it be:
printf("%s", (*_string) -> data);

Were you trying to do something like this?
#include
#include
#include

typedef struct dString_struct{
int size;
char* data;
}dString;

void dString_init(dString** t, int initSize){
*t = malloc(sizeof(dString));
(*t)->size = initSize;
(*t)->data = malloc(sizeof(char)*initSize);
}

int main(){
dString* string = NULL;
char* newString = "randomStuff";
dString_init(&string, 12);
strcpy(string->data, newString);
printf("%s\n", string->data);
free(string->data);
free(string);
return 0;
}

Alright well thanks for the help Sup Forums

Also, it wasn't that the the print somehow failed like you implied. A debug tip: If you had tried writing the numeric value of the char (yes, you wrote the char and not the string, not sure if intended) you would have seen that the write must have failed.

I know, I was just doing some testing.

Why not just something like this? IMO you should avoid memory management where possible.

#include

typedef struct {
int length;
char* data;
} string;

void string_init(string* target, int length) {
target->length = length;
target->data = malloc(length);
}

void string_destroy(string* target) {
free(target->data);
}

int main(int argc, char** argv) {
string example;

string_init(&example, 8);
string_destroy(&example);

return 0;
}

because I need the strings to be resizable.

They still would be. You just need to change length/size and realloc data, which is essentially what you're already doing.

Sup Forums is not stack exchange.