I'm using global structure so I can set/get error or state from everywhere. It was working fine, now I'm in trouble.
structure
typedef struct program Program;
struct program
{
int error;
int state;
};
// global declarations
Program *program;
init
void init_memory(void)
{
program = malloc(sizeof(Program));
if(program == NULL)
{
print_error(E_MEM_ALLOC);
exit(EXIT_FAILURE);
}
program->state = S_NONE;
program->error = E_OK;
}
here program crashes, when I remove "program->error = ...." program is working fine...i don't know why :/
void check_file(char *filename)
{
FILE *file = fopen(filename, "r");
if(file == NULL)
{
program->error = E_FILE_OPEN;
return;
}
fclose(file);
}
whole program: http://pastebin.com/dwSVQ9x8
Making program a pointer seems unnecessary, why not just make it the actual struct:
Program program = { .error = E_OK, .state = S_NONE };
Then you don't need to worry about allocating it (and can indeed remove init_memory altogether). Just change access to its members to use . instead of ->, i.e., program.error = E_FILE_OPEN.
Related
I am making a config reader for an application I am making. What I am trying to fix is that whenever I add another entry '{}' to the config, it will break the application. I have pinpointed the problem, but have no idea how to go about this.
C (config.c):
#include <config.h>
struct Config read_config(char * cfg) {
struct Config newCfg;
newCfg.valuesSize = 0;
int configIsMalloc = 0;
char * config;
if (file_exists(cfg)==0) {
config = cfg;
}
else {
config = read_file(cfg);
configIsMalloc=1;
}
newCfg.values = (char****)malloc(sizeof(char****)*strlen(config));
int valuesPtr = 0;
int needsMalloc = 1;
while(config) {
char * nextLine = strchr(config, '\n');
if (nextLine) *nextLine = '\0';
printf("%s\n", config);
if (config[0] == '{') {
if (needsMalloc==0) {
//newCfg.values[newCfg.valuesSize] = (char***)realloc(newCfg.values[newCfg.valuesSize], newCfg.valuesSize*(sizeof(char***)*sizeof(config)));
}
else {
newCfg.values[newCfg.valuesSize] = (char***)malloc(sizeof(char***)*strlen(config));
needsMalloc=0;
}
}
else if (strstr(config, "}")) {
newCfg.valuesSize++;
valuesPtr=0;
}
// The culprit lies here...
else if (strstr(config, ":")) {
newCfg.values[newCfg.valuesSize][valuesPtr] = (char**)malloc(1000);
char * split = strtok(config, ":");
newCfg.values[newCfg.valuesSize][valuesPtr][0] = (char*)malloc(strlen(split)*sizeof(char));
strcat(newCfg.values[newCfg.valuesSize][valuesPtr][0], split);
split = strtok(NULL, ":");
newCfg.values[newCfg.valuesSize][valuesPtr][1] = (char*)malloc(sizeof(split)*sizeof(char));
strcat(newCfg.values[newCfg.valuesSize][valuesPtr][1], split);
valuesPtr++;
}
if (nextLine) *nextLine = '\n';
config = nextLine ? (nextLine+1) : NULL;
}
(configIsMalloc==1) ? free(config) : NULL;
return newCfg;
}
config.h defines the struct for storing config information C (config.h):
#ifndef CONFIG_H
#define CONFIG_H
#include <string.h>
#include <stdlib.h>
#include <files.h>
struct Config {
char *** values;
int valuesSize;
};
struct Config read_config(char * cfg);
#endif
This contains information for the config reader to pick up This is read from a file in my program test-config:
{
ID:001
TITLE:Russian Spy Infiltration
DESCRIPTION:Those darn russian spies have done it again.
}
{
ID:002
TITLE:American Enthusiasts
DESCRIPTION:America!!!!!
}
The error that prints
{
ID:001
TITLE:Russian Spy Infiltration
DESCRIPTION:Those darn russian spies have done it again.
}
{
ID:002
malloc(): corrupted top size
fish: Job 1, './bm' terminated by signal SIGABRT (Abort)
EDIT: Instead of using sizeof(), I replaced them with strlen()
newCfg.values[newCfg.valuesSize][valuesPtr][0] = (char*)malloc(sizeof(split)*sizeof(char));
Why sizeof(split)? That's the same as sizeof(char*), which is obviously wrong. Did you mean to use strlen?
Also, given `
struct Config {
char *** values;
int valuesSize;
};
and
char * config;
this line has two problems:
newCfg.values = (char****)malloc(sizeof(char****)*sizeof(config));`
First, sizeof(config) is the size of the pointer, not what it points to (and it points to a char of size one...). You probably wanted strlen(). Maybe.
And you are using sizeof(char****) even though values is a char ***. That won't cause a problem with the size on most systems, but it's still wrong. And if you follow the pattern, it will cause serious problems with smaller numbers if *s.
And many would say there's a third problem - you don't cast the return value from malloc() in C.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I've been trying to work with structures, pointers and memory in C.
I have created this structure
typedef struct {
int id;
char *name;
} Object;
here is constructor
void object_ctor(Object *o, int id, char *name)
{
o->id = id;
o->name = malloc(sizeof(name));
if(sizeof(o->name)!=sizeof(name))
{
o->name=NULL;
}
else
{
strcpy(o->name, name);
}
}
here is decleration of o1
char tmp_name[] = "Hello 1";
Object o1;
object_ctor(&o1, 1, tmp_name);
here is destructor
void object_dtor(Object *o)
{
if(o->name != NULL)
{
free(o->name);
o->name = NULL;
}
}
printing object
void print_object(Object *o)
{
printf("ID: %d, NAME: %s\n", o->id, o->name);
}
calling copy
Object copy;
print_object(object_cpy(©, &o1));
and I´m trying create a copy of one structure to another (I have already constructed them).
Object *object_cpy(Object *dst, Object *src)
{
if(src!=NULL)
{
const size_t len_str=strlen(src->name)+1;
dst->name = malloc(10000000);
dst->id = src->id;
strncpy (dst->name, src->name,len_str);
}
if (strcmp(dst->name,src->name)!=0)
{
dst->name = NULL;
}
return dst;
}
But then when I'm trying to free both copy and original src I get a segmentation fault. I've been trying to run it through gdb and it said that I'm freeing same memory twice so I assume that the code for copying is wrong, but I don't know where.
And here is code that gives me segmentation fault
printf("\nCOPY EMPTY\n");
object_dtor(©);
o1.id = -1;
free(o1.name);
o1.name = NULL;
object_cpy(©, &o1);
print_object(©);
print_object(&o1);
I´m including these libraries
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
I'm using the std=c99 flag for to compile.
There is at least a problem here:
void object_ctor(Object *o, int id, char *name)
{
o->id = id;
o->name = malloc(sizeof(name));
if (sizeof(o->name) != sizeof(name))
{
o->name = NULL;
}
else
{
strcpy(o->name, name);
}
}
sizeof(name) is not the length of the string pointed by name. You need strlen(name) + 1 (+1 for the NUL terminator).
And your test if (sizeof(o->name) != sizeof(name)) is pointless, and I'm not sure what you're trying to achieve here.
You probably want this:
void object_ctor(Object *o, int id, char *name)
{
o->id = id;
o->name = malloc(strlen(name) + 1);
if (o->name != NULL)
strcpy(o->name, name);
}
There are similar problems in object_cpy:
pointless use of strncpy
pointless allocation of a 10Mb buffer
pointless test strcmp(dst->name, src->name)
You probably want this:
Object *object_cpy(Object *dst, Object *src)
{
if (src != NULL)
{
const size_t len_str = strlen(src->name) + 1;
dst->name = malloc(len_str);
if (dst->name != NULL)
{
dst->id = src->id;
strcpy(dst->name, src->name);
}
}
return dst;
}
With these corrections following code works fine:
int main()
{
char tmp_name[] = "Hello 1";
Object o1, copy;
object_ctor(&o1, 1, tmp_name);
object_cpy(©, &o1);
print_object(©);
print_object(&o1);
object_dtor(&o1);
object_dtor(©);
}
Event if this is not directly an answer to your problem, I'll give you how I organize my code in order to avoid memory problem like yours.
First, it all resolve around a structure.
To each structure, if needed, I do a "Constructor" and a "Destructor".
The purpose of the constructor is simply to set the structure in a coherent state. It can't never fail (implying that any code that could fail, like malloc, should not be in the constructor).
The purpose of the destructor is to clean the structure.
One little trick that I like to use is to put the constructor in a macro, allowing me to do something like 'Object var = OBJET_CONSTRUCTOR'.
Of course, it's not alway possible, it's up to you to be carreful.
For your code, it could be :
typedef struct {
int id;
char *name;
} Object;
#define OBJECT_CONSTRUCTOR {.id = -1,\ \\ Assuming -1 is relevant in your case, like an error code or a bad id value. Otherwise, it's useless.
.name = NULL}
void Object_Constructor(Object *self)
{
Object clean = OBJECT_CONSTRUCTOR;
*self = clean;
}
void Object_Destructor(Object *self)
{
free(self->name);
}
Here we go.
How to use it is simple : You always begin by the constructor, and you alway end by the destructor. That's why it's useless to set the char pointer "name" to NULL in the destructor, because it should not be used after by any other function that the constructor.
Now, you can have "initialisation" function. You can do a plain initialisation (it is your constructor function), or a copy initialisation, etc etc
Just keep in mind that the structure have been called into the constructor. If not, it's the developer fault and you do not have to take that in count.
A behavior that can be nice is, in case of error, to not modify the structure.
Either the structure is entierly modified in succes, or not at all.
For complex structure that can fail at many point, you can do that by "swapping" the result at the end.
void Object_Swap(Object *first, Object *second)
{
Object tmp = OBJECT_CONSTRUCTOR;
tmp = *fisrt;
*first = *second;
*second = tmp;
}
bool Object_InitByPlainList(Object *self, int id, consr char *name)
{
Object newly = OBJECT_CONSTRUCTOR;
bool returnFunction = false;
newly.id = id;
if (!(newly.name = strdup(name))) {
printf("error : %s : strdup(name) : name='%s', errno='%s'.\n", __func__, name, strerror(errno));
goto END_FUNCTION;
}
// Success !
Object_Swap(self, &newly);
returnFunction = true;
/* GOTO */END_FUNCTION:
Object_Destructor(&newly);
return (returnFunction);
}
It may be seem overcomplicated at the first glance, but that organization allow you to add more futur step "that can fail" cleanly.
Now, you can even do something this simply :
bool Object_InitByCopy(Object *dst, Object *src)
{
return (Object_InitByPlainList(dst, src->id, src->name));
}
All you have to do is to say in the documentation :
The first function to be called have to be "Object_Constructor"
After the "Object_Constructor", only the "Object_Init*" function can be called.
The last function to be call have to be "Object_Destructor"
That's all. You can add any "Object_*" function that you whant, like :
void Object_Print(const Object *self)
{
printf("ID: %d, NAME: %s\n", self->id, self->name);
}
Hope this organization will solve your memory problem.
An example :
int main(void)
{
Object test = OBJECT_CONSTRUCTOR;
Object copy = OBJECT_CONSTRUCTOR;
if (!Object_InitByPlainList(&test, 1, "Hello World !")) {
// The function itself has logged why it has fail, so no need to add error printf here
return (1);
}
Object_Print(&test);
if (!Object_Copy(©, &test)) {
return (1);
}
Object_Destructor(&test);
Object_Destructor(©);
return (0);
}
So I've got a weird problem and can't seem to solve it. I have an ADT called TEAM:
typedef struct Team {
char *name;
int points;
int matches_won;
int goal_difference;
int goals_for;
}TEAM;
I created a function to initialize variables of the TEAM* type with a given name:
TEAM *createTEAM (char *name){
int error_code;
if (name != NULL){
if(strcmp(name, "") != 0){
TEAM *new_team = (TEAM*)malloc(sizeof(TEAM));
new_team->name = (char*)malloc(sizeof(char)*strlen(name));
strcpy(new_team->name, name);
new_team->points = 0;
new_team->matches_won = 0;
new_team->goal_difference = 0;
new_team->goals_for = 0;
return new_team;
}else{
error_code = EMPTY_STRING_CODE;
}
} else {
error_code = NULL_STRING_CODE;
}
printf("Erro ao criar time.\n");
printError(error_code);
return NULL;
}
I also created a function to delete one of these TEAM* variables properly:
void deleteTEAM (TEAM *team_to_remove){
free(team_to_remove->name);
team_to_remove->name = NULL;
free(team_to_remove);
team_to_remove = NULL;
}
But when one or multiple test functions that I created (example below) run, the program sometimes crashes, sometimes doesn't. I've noticed that changing the names I use affects whether it crashes or not, even if they don't affect the test results.
int create_team_01(){
int test_result;
TEAM *Teste = createTEAM("Cruzeiro");
if (strcmp(Teste->name, "Cruzeiro") == 0){
test_result = TRUE;
}else test_result = FALSE;
_assert(test_result); //just a macro function that will check the argument and return 1 if it's false
deleteTEAM(Teste);
return 0;
}
I don't see any problems with memory allocation or freeing. Still, the debugger complains a lot about the first free() (can't find bounds) of the deleteTEAM function. Any ideas? Thanks a lot in advance for any help.
P.S.: I've even tried checking the mallocs' results, but it doesn't seem to be the problem either, so I removed it for the sake of simplicity.
I'm new to C and would like some help with an issue I have. I'm reading and writing to pipes as follows:
f = fdopen(fdH2P[WRITE], "w"); // writing to pipe, returns a file pointer
and
r = fdopen(fdP2H[READ], "r"); // reading from pipe
I want to return both these file pointers from my function. What's the best way to do that?
You can either put the two file pointers into a structure and return that, or you can pass pointers to the function, like this
void GetPipes( FILE **wptr, FILE **rptr )
{
*wptr = fdopen(fdH2P[WRITE], "w");
*rptr = fdopen(fdP2H[READ], "r");
}
void SomeOtherFunction( void )
{
FILE *wptr, *rptr;
GetPipes( &wptr, &rptr );
...
}
You can return a struct:
Define struct, with typedef for convenience
typedef struct dual_fp {
FILE *read_fp;
FILE *write_fp;
} dual_fp;
Add function to open two files
dual_fp dual_fdopen(int write_fd, int read_fd) {
dual_fp ret;
// review error handling and reporting,
// such as add error code fields to struct dual_fp,
// and possibly do not open 2nd / close 1st file if the other fails
ret.write_fp = fdopen(write_fd, "w");
if (!ret.write_fp) perror("dual_fdopen for write");
ret.read_fp = fdopen(read_fd, "r");
if (!ret.read_fp) perror("dual_fdopen for read");
return ret;
}
Call it
dual_fp fps = dual_fdopen(fdH2P[WRITE], fdopen(fdP2H[READ]);
// use fps.read_fp and fps.write_fp after checking they are not NULL
Create a struct and return an instance of the struct.
typedef struct
{
FILE* write;
FILE* read;
} FilePointers;
FilePointers foo()
{
// Assuming you have access to the data...
FILE* w = fdopen(fdH2P[WRITE], "w");
FILE* r = fdopen(fdP2H[READ], "r");
FilePointers fp = {w, r};
return fp;
}
Guys so I'm working on the web service assignment and I have the server dishing out random stuff and reading the uri but now i want to have the server run a different function depending on what it reads in the uri. I understand that we can do this with function pointers but i'm not exactly sure how to read char* and assign it to a function pointer and have it invoke that function.
Example of what I'm trying to do: http://pastebin.com/FadCVH0h
I could use a switch statement i believe but wondering if there's a better way.
For such a thing, you will need a table that maps char * strings to function pointers. The program segfaults when you assign a function pointer to string because technically, a function pointer is not a string.
Note: the following program is for demonstration purpose only. No bounds checking is involved, and it contains hard-coded values and magic numbers
Now:
void print1()
{
printf("here");
}
void print2()
{
printf("Hello world");
}
struct Table {
char ptr[100];
void (*funcptr)(void)
}table[100] = {
{"here", print1},
{"hw", helloWorld}
};
int main(int argc, char *argv[])
{
int i = 0;
for(i = 0; i < 2; i++){
if(!strcmp(argv[1],table[i].ptr) { table[i].funcptr(); return 0;}
}
return 0;
}
I'm gonna give you a quite simple example, that I think, is useful to understand how good can be functions pointers in C. (If for example you would like to make a shell)
For example if you had a struct like this:
typedef struct s_function_pointer
{
char* cmp_string;
int (*function)(char* line);
} t_function_pointer;
Then, you could set up a t_function_pointer array which you'll browse:
int ls_function(char* line)
{
// do whatever you want with your ls function to parse line
return 0;
}
int echo_function(char* line)
{
// do whatever you want with your echo function to parse line
return 0;
}
void treat_input(t_function_pointer* functions, char* line)
{
int counter;
int builtin_size;
builtin_size = 0;
counter = 0;
while (functions[counter].cmp_string != NULL)
{
builtin_size = strlen(functions[counter].cmp_string);
if (strncmp(functions[counter].cmp_string, line, builtin_size) == 0)
{
if (functions[counter].function(line + builtin_size) < 0)
printf("An error has occured\n");
}
counter = counter + 1;
}
}
int main(void)
{
t_function_pointer functions[] = {{"ls", &ls_function},
{"echo", &echo_function},
{NULL, NULL}};
// Of course i'm not gonna do the input treatment part, but just guess it was here, and you'd call treat_input with each line you receive.
treat_input(functions, "ls -laR");
treat_input(functions, "echo helloworld");
return 0;
}
Hope this helps !