user220755
user220755

Reputation: 4446

Memory management in C

Suppose I have a structure, and a pointer to a memory location p, how do I make sure that while creating an instance 'a' of the structure, it is placed into a memory chunk starting at p?

So I am passed a chunk of memory and I want to create a node at the beginning of it, so I need to make sure that the node is created at the beginning of it. (Note: I cannot use malloc, calloc, free, memcpy, or similar functions because I am writing code for a memory management system).

Upvotes: 1

Views: 473

Answers (9)

Charles Eli Cheese
Charles Eli Cheese

Reputation: 783

You asked just the right person. Not specifically, of course.

The answer depends on your OS. If you truly can't use anyone else's memory stuff, then you have your work cut out for you. You will have to make some kind of heap structure(s), perhaps some free list allocators for fixed size, and figure out what the OS has to offer. You have VirtualAlloc in windows and you have brk or similar in unix.

If this is really homework, this is way too much work if this is a single semester assignment.

Of course if all you want to know is how to prepend allocation size to what you return, just do whatever your code normally is, then put your value at the front, then advance the pointer by one and return that.

Upvotes: 0

Steve Jessop
Steve Jessop

Reputation: 279255

Code example for what Alex says:

struct foo {
    int a;
    char *b;
    float c;
};

struct enough_space_for_a_foo {
    char a[sizeof(struct foo))];
};

int main() {
    // region of memory, which in the real code someone else is giving us
    struct enough_space_for_a_foo memory_region;

    // temporary object
    struct foo tmp = {10, "ten", 10.0};

    // copied to the specified region
    memcpy(&memory_region, &tmp, sizeof(struct foo));
}

So, an arbitrary memory region now contains the same values as if it had been initialized as a struct foo, using the initializer expression {10, "ten", 10.0}.

If your struct doesn't need initializing with particular values, then you don't need to do anything. A region of memory in C basically is an instance of a struct if you choose to think of it as one (and it's big enough, and correctly aligned). There are no constructors, so just cast the pointer and get on with filling in the fields.

Upvotes: 0

paxdiablo
paxdiablo

Reputation: 881423

You don't really 'create' instances of structures in C like that. Assuming that p points to a block of usable memory, you can just treat p as a pointer to your structure type:

typedef struct {int x; long y;} a;

a *p2 = (a*)p;
int z = p2->x;

// or, if you don't want p2:
z = ((a*)p)->x;

Once p is cast (implicitly or explicitly as above), you can initialize the contents of your structure however you wish.

As an example, the following code will initialize a structure as you seem to request:

typedef struct {int x; float y;} tA;
void initA (void *p) {
    tA *p2 = (tA*)p;
    p2->x = 0;
    p2->y = 3.14159;
}
int main (void) {
    char bigmem[100];
    initA (&(bigmem[0]));
    return 0;
}

Don't get hung up on the main function above, it's only to illustrate how you can pass an arbitrary memory address to the function. In your real-world case, you will have the memory already allocated somehow.

Upvotes: 7

Igor Zevaka
Igor Zevaka

Reputation: 76500

Sounds like you are trying to do something similar to C++ placement new.

I think you confusing C with higher level languages. You never instantiate structs. You just allocate a bunch of memory and then cast those to a a struct pointer. Alternatively you allocate it on a stack which just means that compiler reserves so many bytes for you to use.

Upvotes: 0

Will Hartung
Will Hartung

Reputation: 118641

typedef struct {int x; long y;} A;

// Populate the members individually
A *aPtr = malloc(sizeof(A));
aPtr->x = 1;
aPtr->y = 2;

or

A *aPtr = malloc(sizeof(A));
A a;

a.x = 1;
a.y = 2;

// Use C's inherent "assignment == copy by value" capability
*aPtr = a;

or

A *aPtr = malloc(sizeof(A));
A a;

a.x = 1;
a.y = 2;

// Copy the memory yourself
memcpy(aPtr, &a, sizeof(A));

Feel free to replace my malloc with your own malloc.

Upvotes: 0

Jerry Coffin
Jerry Coffin

Reputation: 490118

Basically, you take the address and cast it to a pointer of the appropriate type. The major problem you can run into is alignment: if the address isn't properly aligned for an object of that type, attempting to dereference the pointer can (and will) cause undefined behavior -- a typical reaction will be your program being aborted. If memory serves, a typical Unix kernel will give you an error message about a "bus error".

Upvotes: 1

Alex Budovski
Alex Budovski

Reputation: 18446

You can't control where the allocator will allocate memory from, but you can make a temporary instance (on the stack) and copy it into where p points with memcpy.

(Assuming p points to validly allocated memory, large enough for your structure and aligned appropriately.)

Upvotes: 0

Tony van der Peet
Tony van der Peet

Reputation: 824

If creation of the instance 'a' involves allocation of memory, then you can't make that allocation occur at memory pointed to by 'p'.

However, if by creation you mean initialisation of a structure in already allocated memory, then you should be able to pass 'p', typecast to a pointer to the structure, to the initialisation routine. But you will have to be careful that the memory pointed to by 'p' is large enough for the structure, is not being used for something else, and has the right alignment for the structure you are initialising.

If you are actually trying to do something else, you should post some code or go into a bit more detail.

Upvotes: 3

Ass3mbler
Ass3mbler

Reputation: 3915

just typecast the pointer to the type of your struct and you are done...

Hope it helps!

Upvotes: 1

Related Questions