So while testing my struct I use the following method. You can see that I call free on the pointer at the end of the method. Is this right?
void test() {
VariableVector *labelVector = initVariableVector();
VariableVector *variableVector = initVariableVector();
// do some stuff with labelVector and variableVector
free(labelVector);
free(variableVector);
}
This is what my struct init methods look like:
Variable* initVariable(char *variableName, char *arrayOfElements,
int32_t address) {
Variable* initializedVariable = malloc(sizeof(Variable));
if (initializedVariable != NULL ) {
initializedVariable->variableName = variableName;
initializedVariable->arrayOfElements = arrayOfElements;
initializedVariable->address = address;
return initializedVariable;
} else {
return NULL ;
}
}
VariableVector* initVariableVector() {
VariableVector* initializedVariableVector = malloc(
sizeof(VariableVector));
if (initializedVariableVector != NULL ) {
initializedVariableVector->size = 0;
initializedVariableVector->capacity = VECTOR_INITIAL_CAPACITY;
initializedVariableVector->variables = malloc(
sizeof(Variable) * VECTOR_INITIAL_CAPACITY);
return initializedVariableVector;
} else {
return NULL ;
}
}
Your idea is correct, but your implementation is not.
initVariableVector() does 2 malloc's for one object, but you only do 1 free.
You should have function to destroy it too.
void destroyVariableVector(VariableVector* vector)
{
if(vector) {
free(vector->variables);
free(vector);
}
}
EDIT: You're not checking whether the memory allocation for the member "variables" in structure VariableVector is successful. Which means that even at the end you do not free it manually, so it leads to memory leak.
My advice:
Use "init*" functions, but at the same time use "free*" functions. It keeps the code clearer and takes care of all memory releasing.
initVariableVector, the opposite should be freeVariableVector
And the latter function could look like:
void freeVariableVector(VariableVector *vv)
{
if (vv) {
if (vv->variables)
free(vv->variables);
free(vv);
}
}
Related
i need to create a thread pool it,it works but in function do_work that the function pthread_create calls i have problem in the free (memory leak) just when calling pthread_exit()
*in function create threadpool i just initilaize the struct and call
function do work *
void* do_work(void* p)
{
threadpool* pool = (threadpool*)p;
work_t* work;
while(1)
{
pthread_mutex_lock(&pool->qlock);
if(pool->shutdown == 1)
{
pthread_mutex_unlock(&pool->qlock);
//pthread_exit(EXIT_SUCCESS);// here is the free problem when deleting it all good
return NULL;
}
while(!pool->qsize)
{
if(pthread_cond_wait(&pool->q_not_empty,&pool->qlock))
perror("pthread_cond_wait\n");
if(pool->shutdown)
break;
}
//Check if the system is shutting down
if(pool->shutdown == 1)
{
pthread_mutex_unlock(&pool->qlock);
//pthread_exit(EXIT_SUCCESS);y
return NULL;
}
work = pool->qhead; //set the cur variable.
pool->qsize--; //decriment the size.
if(pool->qsize == 0) {
pool->qhead = NULL;
pool->qtail = NULL;
}
else {
pool->qhead = work->next;
}
if(pool->qsize == 0 && ! pool->shutdown) {
//the q is empty again, now signal that its empty.
pthread_cond_signal(&(pool->q_empty));
}
pthread_mutex_unlock(&(pool->qlock));
(work->routine) (work->arg); //actually do work.
free(work);
}
}
The pattern looks like a fairly standard thread pool:
typedef struct {
pthread_mutex_t qlock;
pthread_cond_t q_not_empty;
volatile work_t *qhead;
volatile work_t *qtail;
size_t qsize; /* Not needed */
volatile int shutdown;
} threadpool;
Properly indenting OP's code would make it more readable.
However, the implementation looks odd. I would expect
void *do_work(void *poolptr)
{
threadpool *const pool = poolptr;
work_t *work;
pthread_mutex_lock(&(pool->qlock));
while (!(pool->shutdown)) {
if (!(pool->qhead)) {
/* Queue empty */
pthread_cond_wait(&(pool->q_not_empty), &(pool->qlock));
continue;
}
work = pool->qhead;
pool->qhead = work->next;
if (!pool->qhead)
pool->qtail = NULL;
work->next = NULL;
pthread_unlock(&(pool->qlock));
work->process(work);
pthread_lock(&(pool->qlock));
}
pthread_mutex_unlock(&(pool->qlock));
return (void *)0;
}
and the code that appends a new work item to the queue to be
void append(threadpool *pool, work_t *work)
{
work->next = NULL;
pthread_mutex_lock(&(pool->qlock));
if (pool->qtail) {
pool->qtail->next = work;
pool->qtail = work;
} else {
pool->qhead = work;
pool->qtail = work;
}
pthread_cond_signal(&(pool->q_not_empty));
pthread_mutex_unlock(&(pool->qlock));
}
It is difficult to say where OP's implementation leaks memory. The most likely candidate is OP's arg member in each work_t, if it is dynamically allocated.
My implementation above passes the entire work_t to the routine function, which I renamed to process. It is responsible for freeing the work structure, too. The minimal definition for the work structure is
typedef struct work_t {
struct work_t *next;
void (*process)(struct work_t *);
/* Optional other fields */
} work_t;
Other possible causes for the memory leaks is if the qsize member is not properly updated everywhere. Because there is no use for it, really, I just omit it altogether.
The simpler the code, the easier it is to avoid bugs.
I have a struct which has a char * to act as it's name for finding it. I also have an array of struct declared. I am trying to assign a struct a name, but the problem I am having is the char * is continuing to change values to whatever the last name is set. This is wrecking havoc for the logic of my code. I have tried using malloc(), but that did not change the results.
code:
struct foo {
char* label;
}
typedef struct foo fum;
fum foolist[25];
/*initialize all elements in foo list to be "empty"*/
bool setArray(char* X) {
for(int i =0; i <25;i++) {
if(strncmp("empty", foolist[i].label,5*sizeof(char))==0) {
//tried char* temp = (char*)malloc(32*sizeof(char));
//foolist[i].label = temp; no change.
foolist[i].label = X;
return true;
}
}
return false;
}
I want label to not change with 'X' once the declaration is made, i have tried using malloc(), probably not correctly though.
You can do either:
foolist[i].label = malloc(strlen(X) + 1);
if ( !foolist[i].label ) {
perror("couldn't allocate memory"):
exit(EXIT_FAILURE);
}
strcpy(foolist[i].label, X);
or, if you have strdup() available:
foolist[i].label = strdup(X);
if ( !foolist[i].label ) {
perror("couldn't allocate memory"):
exit(EXIT_FAILURE);
}
Hi I was trying to write a function that takes in the head of a linked list and free all the memory it allocated. Here is the original code I wrote.
void clear_nodes(List *h) {
if (!h->next) {
free(h);
***h = NULL;***
}
else {
clear_nodes(h->next);
clear_nodes(h);
}
}
However it does not work. So I changed it to
void clear_nodes(List *h) {
if (!h->next) {
free(h);
}
else {
clear_nodes(h->next);
***h->next = NULL;***
clear_nodes(h);
}
}
and now it worked.
Notice the difference between the two, I just wonder why can't I make the pointer to null directly. Is it because it's a local variable or something? But marking a pointer to null should make the pointer point to some memory address that I can't access right? Why would it matter if I do it locally or globally.
Thank you guys in advance.
I would probably do this NON-RECURSIVELY
void clear_nodes(List **h) {
List * copy = *h;
while( (copy = (*h)->next) != NULL){
free(*h);
*h = NULL;
*h = copy;
}
}
Recursivity is generally slower than looping. If you can try to design without recursive routines.
Since the value of h was passed, and not the location, you are not changing the pointer - you are changing a copy of the pointer.
If you changed your function to
void clear_nodes(List **h) {
if ((*h)->next == NULL) {
free(*h);
*h = NULL;
}
else {
clear_nodes(&((*h)->next));
clear_nodes(h);
}
}
You could change it "locally". I think I got that second part right... didn't try to compile / run it. I am positive about the first part though.
I'm trying to implement a stack structure in C, for storing char arrays into.
I have the following code:
typedef struct {
size_t size;
char **data;
} loods1;
loods1 *init(void) {
loods1 *loods = malloc(sizeof(loods1));
loods->data = malloc(sizeof(char *) * STACK_MAX);
for (int i = 0; i < STACK_MAX; i++) {
*(loods->data + i) = malloc(LABEL_LENGTH_MAX * sizeof(char));
}
loods->size = 0;
if (loods == NULL) {
perror("malloc failed\n");
return NULL;
}
return loods;
}
int empty(loods1 *loods) {
return (loods->size == 0);
}
void push(loods1 *loods, char *name) {
if (loods->size == STACK_MAX) {
perror("Stack is full\n");
exit(0);
}
else {
*((loods->data) + loods->size++) = name;
}
}
char *pop(loods1 *loods) {
if (loods->size == 0) {
printf("size == 0\n");
return NULL;
}
else {
printf("%s \n", *(loods->data + 1));
return *(loods->data + (--loods->size));
}
}
int delete(loods1 *loods) {
for (int i = 0; i < STACK_MAX; i++) {
free(*(loods->data + i));
}
free(loods->data);
free(loods);
}
There are 2 problems: first off, every time I add a new element to the stack, it overwrites all existing elements (if '3' and '11' are added and I want to add '15', the new stack will look like '15', '15', '15'). And when I want to pop the stack, the popped value is empty. Not null, but an empty string or something?
I have no idea what I'm doing wrong, but there seems to be a mistake somewhere, obviously.
Sammy
In push function, if you are passing char*, it will divert your pointer to where the char * is, and when you do p++, it will go from the char* you passed.
Try change push definition to:
void push(loods1 *loods, const char *name) {
if (loods->size == STACK_MAX) {
perror("Stack is full\n");
exit(0);
}
else {
strcpy((loods->data)[loods->size++], name);
}
}
From here you might as well need some other changes to your calling program.
Also when you free it, free the single loods does not free all memory you allocated.
I flicked through the code and it seems to be ok, I think the problem is in your client.
Your only store pointers in the stack, you're probably pushing the same pointer on the stack but rewrite the string it points to.
Note that if you really only want to store pointers your 3rd malloc is wasting space and also creates a memory leak.
I would like to actually use this wrapper, but the problem is i don't know if it's very safe, yet.
I have a few simple questions regarding using malloc(), calloc(), and realloc(). Here's what I have so far:
string.h
typedef struct str str; // pointer for encapsulation
string.c
struct str
{
char *buf;
size_t len;
}
Say i have a helper function that simply does this:
str *NEW_STRING()
{
str *temp = calloc(1, sizeof (struct str));
temp->len = 0;
temp->buf = (char *) malloc(1);
return temp;
}
Is this safe? If it is, what would happen if i did something like this:
str *A_STRING = NEW_STRING();
A_STRING = NEW_STRING();
It would call malloc and calloc twice, is that bad? Would an initializer be better?
void str_init(str *A_STRING)
{
if (A_STRING)
{
free(A_STRING);
}
if (A_STRING->buf)
{
free(A_STRING->buf);
}
A_STRING = calloc(1, sizeof (struct str));
A_STRING->buf = (char *) malloc(1);
A_STRING->len = 0;
}
Finally, is this a good way to free memory?
void free_string(str *A_STRING)
{
if (A_STRING->buf)
{
free(A_STRING->buf);
}
else
{
A_STRING->buf = NULL;
}
if (A_STRING)
{
free(A_STRING);
}
else
{
A_STRING = NULL;
}
A_STRING->len = 0;
}
Any additional information would be great if included. I don't want to release anything to the public as if it were a good library, because i am primarily doing this for learning purposes.
Lots of errors:
is this safe? if it is, what would happen if i did something like this:
No.
str *NEW_STRING()
{
str *temp = calloc(1, sizeof (struct str));
// If calloc fails and returns NULL all the code below is invalid and blows the code up.
Next:
it would call malloc and calloc twice, is that bad? would an initializer be better?
You leak memory.
The second call basically generates a new object the old object is lost and leaks.
Problems in str_init
void str_init(str *A_STRING)
{
Is this the first time that his method is called?
If so then A_STRING contains a random value (that you are about to FREE).
This will blow the code up.
if (A_STRING)
{
free(A_STRING);
}
A_STRING is freed (you can now no longer accesses it).
Any code that does so is bad.
if (A_STRING->buf) // Bang blow up code.
{
free(A_STRING->buf);
}
A_STRING = calloc(1, sizeof (struct str));
No checking the result of calloc.
A_STRING->buf = (char *) malloc(1);
A_STRING->len = 0;
}
is this a good way to free memory?
void free_string(str *A_STRING)
{
if (A_STRING->buf)
{
free(A_STRING->buf);
}
else
{
A_STRING->buf = NULL; // Its already NULL pointless work
}
if (A_STRING)
{
free(A_STRING);
}
else
{
A_STRING = NULL; // ITs already NULL pointless work
}
// BANG you just blew up the space shuttle.
A_STRING->len = 0;
}