How to initialize a struct in c using posix_memalign - c

I'm trying to figure out how to initialize a struct if I'm passed a memory location, the situation below is what I'm trying to do, but it throws "invalid initializer" shortened to relevant code
#ifndef PAGE_ALLOC_H
#define PAGE_ALLOC_H
typedef struct listNode
{
struct listNode *prev;
struct listNode *next; // prev/next element in linked list
char * address;
} listNode;
#endif
_____________________________________________
#include "page_alloc.h"
#include <stdlib.h>
#include <stdio.h>
int main (int argc, char ** args)
{
void * memptr;
int test = posix_memalign(&memptr, 2, 128); // test is > 1, values such as 16 and 22 is this ok? It does seem to return a valid memory address though, but can't test until struct lets me initialize to it...
listNode testNode = memptr; // this throws improper initialization flag, but how else do I do tell //the struct where the eligible memory is?? Isn't that what malloc does? Return a point to acquired //memory
// Now this is what I imagine doing after telling testNode where its allocated memory
testNode ->prev = somePreviousNode; // etc.
}
I'm obviously doing something wrong but what? I'm sorry if this is a dumb question but I can't find any examples of posix_memalign nor can I find an explanation of properly initializing structs with a pointer to allocated memory. I need to dynamically add nodes because this is for a doubly linked list pointing to memory locations (used for keeping track of "pages")
Thanks for any insight!!!

testNode is an object of the structure and you are assigning a pointer (memptr) to it:
listNode testNode = memptr;
Instead create a pointer to listnode and assign the allocated memory to it:
listNode *testNode = memptr;
Note: The value of the alignment parameter should satisfy two conditions:
should be a multiple of sizeof(void*)
should be a power of 2.
For eg,
if on your machine, sizeof(void*) = 4, then the acceptable value is 4,8,16....
if on your machine, sizeof(void*) = 8, then the acceptable value is 8,16,32...

Related

Allocating memory without using malloc in C

as for a little project, my aim is to add a node at the head of a linked-list and allocate "width" bytes of data for the struct Node structure. Normally, this would be simple as malloc accomplishes this task; however, I've been instructed to use a function called newmalloc, which essentially does the same thing. The newmalloc function returns an integer which is what will be used as the number of bytes to allocate the structure. I have provided my header file which contains the struct, as well as the function in which I am working.
Header.h:
#include <stdio.h>
struct Node {
int data;
int next;
};
void push(int*node_ptr, void*pie, size_t width );
Function.c:
void push(int *node_ptr, void *pie, size_t width) {
struct Node *next, *prev, *head, *p;
newmalloc(width); //Returns number of bytes
}
How do I actually go about allocating memory for the struct Node structure using the returned integer from newmalloc, without using malloc? Thanks for the help!

Why do I get a segfault when trying to access members of struct?

I am getting a segmentation fault whenever I try to print the value stored within a struct. Using Valgrind, I was able to narrow it down a bit to one block of code, but I am unsure what I am doing wrong. Am I initializing my struct incorrectly?
Whenever I run valgrind, it tells me that there is an invalid write of size 8 where I say newList->data = d.
typedef struct List {
struct List *np[Ends]; // next/prev neighbors
Data data;
} *List;
typedef void *Data;
static void put(Data d) {
List newList = malloc(sizeof(List));
newList->data = d;
}
This is an example of why it's bad practice to typedef a pointer.
Because List is defined as an alias for struct List *, sizeof(List) gives you the size of a pointer, not the size of the struct. As a result, you're not allocating enough memory.
You instead want either malloc(sizeof(struct List)) or (preferably) malloc(sizeof *newlist)

C Struct Initialization

#include <stdio.h>
struct node {
int data;
struct node* next;
};
typedef struct node Node;
int main() {
Node a;
a.data = 1;
if (!a.next) {
printf("hello world");
}
}
I'm writing a little linked list program to start learning c, and I'm confused as to why a.next is not null.
In short, whenever you allocate some memory in C (either explicitly or implicitly), the memory is initialized with whatever was there when the stack frame for your main function was created (ie. garbage). This is true of your int value as well (remove the a.data = 1 and print the value of a.data). C doesn't zero the memory it allocates for you (which makes C more efficient). As Anandha suggested, just set the pointer to NULL to avoid this problem.
You should initialize the pointer with NULL, the declared pointer may contain garbage value pointing to anywhere in the memory.
So a.next=NULL

initializing global malloc() of static size

I am having issues with my code. I am supposed to have 4 files. list.h, listAdders.c, listMovers.c, and listRemovers.c.
I am supposed to statically declare 2 blocks of memory for lists and nodes of sizes minList and minNodes. And Malloc() is only allowed to be used at runtime (which means I am not allocating memory as a per-list or per-node basis).
listRemovers.c and listMovers.c will need access to the memory block I allocate using malloc() for my lists and nodes.
There is no init() function, and I don't know how I can malloc() a global variable array which will hold the Lists and Nodes.
Just in case my question is unclear. How do I malloc an initial block of memory for my struct of lists and nodes? So that when I create a list or add a node, they're stored on the memory I allocated.
Here's what I have:
list.h
#ifndef __LIST__
#define __LIST__
#define MIN_LISTS 3
#define MIN_NODES 30
typedef struct NODE{
struct NODE* next;
struct NODE* prev;
} NODE;
typedef struct LIST{
struct NODE* head;
struct NODE* cursor;
int size;
} LIST;
extern NODE *node_block;
extern LIST *list_block;
LIST *ListCreate();
int ListAdd(LIST *list, void* item);
#endif // __LIST__
listAdders.c
#include "list.h"
#include <stdlib.h>
#include <stdio.h>
NODE *node_block = malloc(MIN_NODES * sizeof(struct NODE));
LIST *list_block = malloc(MIN_LISTS * sizeof(struct LIST));
LIST *ListCreate()
{
}
int ListAdd(LIST * list, void* item)
{
}
There is no init() function, and I don't know how I can malloc() a global variable array which will hold the Lists and Nodes.
C does not allow executable code outside of actual functions.
So this code will not compile:
NODE *node_block = malloc(MIN_NODES * sizeof(struct NODE));
LIST *list_block = malloc(MIN_LISTS * sizeof(struct LIST));
Given your problem statement:
I am supposed to statically declare 2 blocks of memory for lists and nodes of sizes minList and minNodes.
Replacing your code above with this code would be a "static declaration":
NODE node_block[ MIN_NODES ];
LIST list_block[ MIN_LIST ];
You could also do something like this:
NODE *node_block;
LIST *list_block;
static void init_memory()
{
node_block = malloc(MIN_NODES * sizeof( *node_block ));
list_block = malloc(MIN_LISTS * sizeof( *list_block ));
}
int main( int argc, char **argv )
{
init_memory();
.
.
.
}
Note that starting with a fixed number of allocated nodes and lists will result in needlessly complex code should you need more nodes and/or lists than you start out with.
Either statically allocate all of your memory, or dynamically allocate all of it. That way your code will be a lot simpler.

Manually allocating memory for a struct

So I am working on a project in C where we need to implement malloc and free (meaning, we CANNOT use any C memory management functions such as malloc() or free()). This is only a code snippet, but it includes all relevant parts.
struct block_header
{
int size;
};
typedef struct FList_elem
{
struct block_header * header;
struct list_elem elem;
} FLelem;
void * manual_malloc(size_t size)
{
freeBlock = (FLelem *) mem_sbrk(newsize);
freeBlock->header = (struct block_header *) freeBlock;
freeBlock->header->size = newsize;
}
When allocating a new "block" of memory, we represent it via a structure FList_elem. In order to "allocate memory" for the struct, we point it at a memory address returned by mem_sbrk (works just like sbrk()). My question is, how do we establish memory for variables like size? Initially it's address is 0x0, and so assignments or references to it cause seg faults. Does it need to be a pointer so that we can set it's address, and then the value?
Instead of your original code, which stores a pointer to block_header inside the FList_elem structure, you can just embed the whole block_header structure inside the FList_elem structure:
struct block_header
{
int size;
};
typedef struct FList_elem
{
/* OLD code: struct block_header * header; */
/* Better code: block_header is embedded inside FList_elem structure */
struct block_header header;
struct list_elem elem;
} FLelem;
In this way, you don't need to allocate block_header separately: it's just there with the rest of FList_elem bytes.
And to set the size field (and any other attribute you may add to your block header) you can just do:
freeBlock->header.size = newsize;
When allocating the requested size, you need to add the header elements - and the pointer to the next block (eventually - the size can be computed with pointer difference as a space optimization... if this is embedded staff they are 4 bytes per block saved).
Since I think there are some incongruences, I have reported here my interpretation (not tested) of what you are trying to do:
struct block_header
{
int size;
};
typedef struct FList_elem
{
struct block_header header; // removed a * here: size is in place
struct Flist_elem *elem; // added a * here: that's the pointer to the next block.
} FLelem;
FLelem *memory_list = 0; // added a pointer for the global list - right?
void * manual_malloc(size_t newsize) // renamed as newsize here
{
freeBlock = (FLelem *) mem_sbrk(newsize + sizeof(FLelem));
freeBlock->header.size = newsize;
freeBlock->header.elem = memory_list;
memory_list = freeBlock;
// inserted freeBlock at the head of memory_list;
return (void*)(freeBlock+1); // +1 to skip the header as a return address
}
The caller of the function will have returned the space after the header.
Your manual_free() function will take as an argument this returned memory pointer, and it will need to subtract and go back a freeblock in memory in order to find the header and to release the block, and than you will need some sort of tree (bit tree) to keep of track of the holes left free... If you need to handle dynamic memory - and that's where it start being interesting.
Hope I have not done errors and that it's clear enough!
#include <stdlib.h>
struct st *x = malloc(sizeof *x);
Note that:
x must be a pointer
no cast is required
include appropriate header

Resources