I don't understand why this program segfaults:#include <stdlib.h>
#include <stdio.h>
#include <string.h>
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.
>>56052274
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?
>>56052579
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 <stdlib.h>
#include <stdio.h>
#include <string.h>
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:
>>56052668
>>56052678
>>56052711
Because otherwise the pointer in main will not be changed to whats allocated in dString_init.
>>56052711
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**.
>>56052772
You don't write properly. The resize is triggered but you don't strcpy after the resize. Tryvoid dString_write(dString** _string, char* input){
if (strlen(input) >= (*_string) -> size)
dString_resize(_string, strlen(input)*10);
strcpy((*_string) -> data, input);
}
>>56052859
goddamit!
>>56052772
>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 <stdlib.h>
#include <stdio.h>
#include <string.h>
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;
}
>>56052872
Alright well thanks for the help /g/
>>56052872
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.
>>56052894
I know, I was just doing some testing.
Why not just something like this? IMO you should avoid memory management where possible.#include <stdlib.h>
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;
}
>>56053045
because I need the strings to be resizable.
>>56053071
They still would be. You just need to change length/size and realloc data, which is essentially what you're already doing.
/g/ is not stack exchange.