I have a question about this code:
typedef struct pop {
unsigned long int *np; // matrix
unsigned long int f;
long double fp;
unsigned long int *R; // matrix
unsigned long int *C; // matrix
unsigned long int Dp;
unsigned long int Ds;
unsigned long int count;
struct popolazione *ptrTempLst; // pointer
struct popolazione *leftTree; // left tree pointer
struct popolazione *rightTree; // right tree pointer
} Node;
When I free space allocated for this struct, prior have I to free pointer to matrix inside struct?
For example,
Node *ptr=(Node *) malloc(sizeOf(Node));
ptr->np=(unsigned long int *)malloc(10*sizeOf(unsigned long int));
/*code code code*/
// is necessary: free(ptr->np);
free(ptr);
Thanks in advance
Yes.
Every call to malloc must have a matching call to free.
That is correct.
To help avoid shooting yourself in the foot, you might consider the following practices:
Always free all malloc/calloc'ed memory with free()
Afterwards, set the pointer to NULL
Use a dedicated cleanup/destroy function to ensure consistent memory cleanup
The following function would be a good way to make sure you always cleanup a structure properly, avoid memory leaks, and avoid accidentally freeing already-freed memory and causing a segmentation fault:
int destroyNode(Node* myNode) {
if(!myNode) {
printf("Invalid pointer! Exiting");
return (-1);
}
// Clear out memory
if(np) {
free(np);
np = NULL;
}
if(R) {
free(R);
R = NULL;
}
if(C) {
free(C);
C = NULL;
}
if(ptrTempLst) {
free(ptrTempLst);
ptrTempLst = NULL;
}
if(leftTree) {
free(leftTree);
leftTree = NULL;
}
if(rightTree) {
free(rightTree);
rightTree = NULL;
}
free(myNode);
}
eg:
int main(void) {
Node *tempNode = calloc((size_t)1,sizeof(Node));
// Alloc the member nodes, etc, do some code
// Ready to clean up and exit program
destroyNode(tempNode);
tempNode = NULL;
return 0;
}
Good luck!
Related
Usually, when I use linked lists, I write:
struct node *startPtr = NULL;
so I check later if is it NULL, and if it is, it means that the list is empty.
But in this code:
struct card{
char face[3];
char suit[4];
};
typedef struct card Card;
struct stack{
Card cardd;
struct stack *nextPtr;
};
typedef struct stack Stack;
int main(){
/*
creation of *stacks also with calloc
*/
Stack *topstacks = calloc(4,sizeof(Stack)); // array of lists initialized by calloc
/*
scanf pos1, pos2 to switch
*/
move_card(stacks, topstacks, pos1, pos2);
}
int move_card(Stack *stacks, Stack *topstacks, unsigned int pos1, unsigned int pos2){
Stack *prevfromPtr;
Stack *fromPtr = &(stacks[pos1]);
Stack *toPtr = &(topstacks[pos2]);
while(fromPtr->nextPtr!=NULL){
prevfromPtr = fromPtr;
fromPtr = fromPtr->nextPtr;
}
Stack *newmovingcard = calloc(1,sizeof(Stack));
newmovingcard->cardd = fromPtr->cardd;
newmovingcard->nextPtr = NULL;
if (toPtr!=NULL){ // here I'd like to check if the list is empty and has not any item. This way it does not work because toPtr can't be NULL, it's a pointer
while(toPtr->nextPtr!=NULL){
toPtr = toPtr->nextPtr;
}
toPtr->nextPtr = newmovingcard;
free(fromPtr);
prevfromPtr->nextPtr = NULL;
return 0;
} else {
toPtr->cardd = newmovingcard->cardd;
toPtr->nextPtr = NULL;
free(fromPtr);
prevfromPtr->nextPtr = NULL;
return 0;
}
}
I have an array of lists (topstacks), initialized with calloc. And in the commented line inside move_card, I need to check if the single list of the array of lists is empty. But I don't know how to do that.
Here is the full code, but some parts with printf are in italian, so sorry for that: https://wtools.io/paste-code/b2gz
You can try to assign nextPtr to the same element or you can introduce a special global item which will mean an empty list.
If you use malloc with memset instead of calloc you can set your value as your own "void" value.
I mean this kind of thing :
int* example;
example=malloc(100*sizeof(int)); // allocate memory to store 100 int
if(example){
memset(example,1,100*sizeof(int)); // initialize it with value 1
}
Working with two linked lists simultaneously is kind of fussy and annoying, but it is doable:
int move_card(Stack **source, Stack **target, int source_pos, int target_pos) {
// Walk through the linked list, but in every case stop one short of the
// insertion point
// Walk through the source chain and identify which pointer needs
// to be manipulated.
for (int i = 0; i < source_pos; ++i) {
if (*source == NULL) {
return -1;
}
source = &((*source)->nextPtr);
}
// Walk through the target chain and identify the insertion point.
for (int i = 0; i < target_pos - 1; ++i) {
if (*target == NULL) {
return 1;
}
target = &((*target)->nextPtr);
}
// Capture the pointer we're actually moving
Stack* moving = *source;
// Skip this link in the chain by reassigning source
*source = moving->nextPtr;
// Capture the record that's being bumped
Stack* bumped = *target;
// Reassign the target
*target = moving;
// Re-link the bumped entry back in the chain
moving->nextPtr = bumped;
return 0;
}
Where I've taken the liberty of renaming a few things to make this easier to understand. Notice how it uses a double pointer so it can manipulate the original pointers if necessary. When removing the first card from a linked list, the pointer to the "head" entry must change.
Here's a more complete "demo" harness for that code:
#include <stdio.h>
#include <stdlib.h>
struct stack {
char card[2];
struct stack *nextPtr;
};
typedef struct stack Stack;
Stack* make_stack(char face, char suit, Stack* nextPtr) {
Stack* stack = calloc(1, sizeof(Stack));
stack->card[0] = face;
stack->card[1] = suit;
stack->nextPtr = nextPtr;
return stack;
}
void print_stack(Stack* stack) {
while (stack) {
printf("%c%c ", stack->card[0], stack->card[1]);
stack = stack->nextPtr;
}
printf("\n");
}
int main(int argc, char** argv) {
Stack* source = make_stack('A', 'S', make_stack('2', 'S', make_stack('3', 'S', NULL)));
Stack* target = NULL;
print_stack(source);
move_card(&source, &target, 2, 0);
print_stack(source);
print_stack(target);
return 0;
}
Where that uses a simplified Card model.
i am studying queue in c and trying to make basic queue program. But couldn't manage to allocate memory for my array. Here is my queue declaration and my createqueue function. After allocating memory space for myQueue, i should allocate for array aswell but i dont know how. Should i just type myQueue->array =(myQueue)malloc(sizeof(myQueue)); will it work ?
struct QueueRecord
{
int capacity;
int front;
int rear;
int size;
int *array;
};
typedef struct QueueRecord *Queue;
Queue CreateQueue(int maxElements)
{
Queue myQueue;
if (maxElements<MIN_QUEUE_SIZE)
{
printf("Queue is too small\n");
return;
}
myQueue = (Queue*)malloc(sizeof(Queue));
if (myQueue == NULL)
printf("out of memmory space");
myQueue->array =(myQueue)malloc(sizeof(myQueue));
myQueue->capacity=maxElements;
MakeEmptyQueue(myQueue);
return myQueue;
}
i should allocate for array aswell but i dont know how
because of the line
myQueue->capacity=maxElements;
the logic is to have
myQueue->array = malloc(sizeof(int) * maxElements);
Should i just type myQueue->array =(myQueue)malloc(sizeof(myQueue)); will it work ?
only in case sizeof(myQueue) is greater than sizeof(int) * maxElements, but you only check maxElements not too small, when maxElements is enough large the behavior is undefined (typically when maxElements is greater than 6 when the size of a pointer is the double of the size of an int).
Out of that :
It is a bad idea to have a typedef defining a pointer, better to have the pointers explicit in the code to see them
the first return; must be return NULL;
knowing myQueue is NULL do not dereference it after, you can directly return NULL after the printf
you check the first malloc does not return NULL, do also for the second, typically in the same if
For instance :
struct QueueRecord
{
int capacity;
int front;
int rear;
int size;
int *array;
};
typedef struct QueueRecord Queue;
void MakeEmptyQueue(Queue *);
Queue * CreateQueue(int maxElements)
{
Queue * myQueue;
if (maxElements < MIN_QUEUE_SIZE)
{
printf("Queue/maxElements is too small\n");
return NULL;
}
if (((myQueue = malloc(sizeof(Queue))) == NULL) ||
((myQueue->array = malloc(sizeof(int) * maxElements)) == NULL))
{
printf("out of memory space\n");
free(myQueue); /* to avoid memory leak, no problem if myQueue is NULL */
return NULL;
}
myQueue->capacity = maxElements;
MakeEmptyQueue(myQueue);
return myQueue;
}
I am reading the script on the implementation of malloc (first-fit), and I am a little confused about the value assignment of metadata structure. Could anyone give some explanations why the malloc returns flag_block->ptr (as a pointer to the allocated memory)? As far as I can see, there is no specific assignment to it.
typedef struct _metadata {
size_t size;
char free;
struct _metadata* next;
struct _metadata* prev;
char ptr[];
} metadata;
metadata* flag_block = NULL;
void *malloc(size_t size)
{
if (size==0) {
return NULL;
}
if (flag_block == NULL) {
flag_block = sbrk(size);
sbrk(sizeof(metadata));
if (flag_block == (void *)-1) {
return NULL;
}
flag_block->free = 0;
flag_block->next=NULL;
flag_block->prev=NULL;
flag_block->size = size;
return flag_block->ptr;
} else {
/*
....
*/
}
}
The ptr is called a flexible array member; it's an array without a size, and can only appear at the end of a struct.
So basically this:
return flag_block->ptr;
is equivalent to
return &flag_block->ptr[0];
So it's returning the address of the first byte after the rest of the members in the struct.
I have been doing excercises from a book. And I am stuck on the meaning of this qustion. Assuming that you store integer values on the stac and that using a static array to store data provide a createStack() deleteStack(stack) methods.
My interpretation is
typedef struct {
int values;
char data[50];
} StackData;
typedef struct n {
StackData d; // store some data in node
struct n *successor; // store successor of node
// as typedef is not yet completed
// name StackNode cannot be used
} SatckNode;
typedef struct {
StackNode *head;
StackNode *current;
} Stacklist;
I know these arent the methods. But i want to know if I am going about it the right way
If you're using a static array for the values, then you don't technically need createStack() and deleteStack() functions, because you can just create a struct stack or whatever on the stack (pun intended) and you're done.
If you do want to, though, (and you might legitimately want to, e.g. to avoid having to explicitly initialize top, or to hide the implementation behind an opaque type, or to be able to return one from a function without copying a potentially large array) this'll do it:
#include <stdio.h>
#include <stdlib.h>
#define STACKSIZE 50
typedef struct stack * Stack;
struct stack {
size_t top;
int values[STACKSIZE];
};
Stack createStack(void)
{
Stack new_stack = malloc(sizeof *new_stack);
if ( !new_stack ) {
perror("couldn't allocate memory");
exit(EXIT_FAILURE);
}
new_stack->top = 0;
return new_stack;
}
void deleteStack(Stack stack)
{
free(stack);
}
void push(Stack stack, const int n)
{
if ( stack->top < STACKSIZE ) {
stack->values[stack->top++] = n;
}
else {
fprintf(stderr, "Stack full - exiting.\n");
exit(EXIT_FAILURE);
}
}
int pop(Stack stack)
{
if ( stack->top > 0 ) {
return stack->values[--stack->top];
}
else {
fprintf(stderr, "Stack empty - exiting.\n");
exit(EXIT_FAILURE);
}
}
int main(void)
{
Stack mystack = createStack();
push(mystack, 3);
push(mystack, 1);
push(mystack, 4);
push(mystack, 1);
push(mystack, 5);
for ( size_t i = 0; i < 5; ++i ) {
printf("Popped %d from stack.\n", pop(mystack));
}
deleteStack(mystack);
return 0;
}
Right now you seem to want a stack with values in a static array, but then you start defining structs for nodes and lists, as if you want a linked list implementation. The two implementations are obviously pretty different.
I think you're on the right way - just a couple of comments.
In Stacklist, I don't get why you have pointers to two of the nodes in the stack.
Usually, stacks only keep a reference to the item on the top of the stack.
In addition, they either keep a counter of how big is the stack, or a pointer to the node on the bottom of the stack (which is what you probably mean by head, and reference the head node by current?).
And don't forget to initialize everything whenever you create any of those structures :P usually ends up in endless hours of headache.
Keep up the good work.
For a prelab (meaning it's not for a grade), I'm supposed to implement my first ever stack using linked lists. I wrote it adding only one thing to the stack just as practice, as to why it's so short. Anyway, I have no compile errors, besides it saying that "new" is uninitialized in my create_stack function. This is also where I'm getting a segmentation fault, as it's not printing out my first printf function. I am also guessing that the problem is bigger than just me initializing the stack, but this is my problem's start. Please go easy on me if it's something simple, as, like I said, it's my first time doing stacks, and thanks for your help.
#include <stdio.h>
#include <stdlib.h>
typedef struct node_{
char data;
struct node_ *next;
}node;
typedef struct stack_{
unsigned int size;
node* stack;
}stack;
stack* create_stack();
void push(stack* s, char val);
char top(stack* s);
void pop(stack*s);
int main(void) {
char value, val;
stack* new = create_stack();
printf("Enter a letter: ");
scanf("%c", &value);
push(new, value);
val = top(new);
printf("%c\n", val);
pop(new);
return 0;
}
stack* create_stack(){ //initializes the stack
stack* new;
new->size = 0;
new->stack = NULL;
return new;
}
void push(stack* s, char val) {
node* temp = (node*)malloc(sizeof(node)); //allocates
if ( temp == NULL ) {
printf("Unable to allocate memory\n");
}
else{
temp->next = s->stack;
temp->data = val;
s->stack = temp;
s->size = (s->size) + 1; //bumps the counter for how many elements are in the stack
}
}
void pop(stack* s) {
node* temp;
temp = s->stack;
s->stack = temp->next;
free(temp);
s->size = (s->size) - 1; //subtracts from counter
}
char top(stack* s) {
node* temp = s->stack;
char value = temp->data;
return value;
}
The reason it crashes is that you never allocate any memory when you create the stack. Do stack* new = malloc (sizeof(stack)); in the create_stack function.
For the future you might want to use better variable names. Using for instance using new as the name for the stack isn't that good - it isn't very descriptive plus it's a reserved keyword in several languages, C++ for example.
stack *new creates a local pointer, but it has nothing to point to yet. Since you want the stack to continue to exist after the function completes, you should allocate memory for it using malloc (and eventually free it using free).
So your create_stack function should start with:
stack* new = malloc(sizeof(stack));
An alternative would be to declare the stack as a local variable in your main function, and pass it as an argument into create_stack to initialize it:
stack new;
create_stack(&new);