开发者

Memory management in C

开发者 https://www.devze.com 2022-12-13 09:58 出处:网络
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?

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 mal开发者_如何学运维loc, calloc, free, memcpy, or similar functions because I am writing code for a memory management system).


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.


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.


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

Hope it helps!


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".


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.)


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.


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.


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消