Given a large struct pointer, say, large_ptr, and I want to assign it to a global var of the same type, let's call it g_large, then I have 2 options:
The first one using memcpy:
memcpy(&g_large, large_ptr, sizeof(g_large));
The second one using assignment:
g_large = *large_ptr;
Due to lack of memory and stack size in an embedded software I would like to know, does the second way behave like memcpy, or does it create a tmp var to do the assignment? Is there any standard for this?
If it behaves like memcpy then I'd prefer it for being shorter. But if it creates a temporary var, it might be a problem for the stack.
Your experience & knowledge will be appreciated!
Edit
A few mentioned I need to compile and view the assembly.
This is a process I need to learn, since it's a cross compiler, which generates asm files that are binary and need to be parsed. Not a simple task. I could do that, but it will take time.
I may misunderstood but in ur memcpy function the sizeof(g_large) will always return 8 bytes as result since the size of a pointer in c is 8 bytes. Therefore you get the pointer size and not the struct size. It's like you can not find the size of an array if you only have the pointer addressing it.
[edit: oh yeah i misunderstood but anyway the following section is still recommended]
What I would do:
dinamically allocate memory in main function
pass the allocated memory pointer to the local function where you want to work with your struct
extend the allocated memory if needed while working with your struct on the designated memory space
at the end of the local function you will already have ur struct stored in main function memory space without any copy function needed
Related
I'm new to C (and structures in C). And I've seen varying code examples across the internet, but what is the benefit of doing this:
void foo(LargeStruct* struct);
instead of this
void foo(LargeStruct struct);
Does it make memory management easier?
The former passes a pointer to the structure to the function. The latter makes a copy of the structure and passes it to the function. If the structure is large, making a copy of it for the function is expensive (uses lots of resources), so it should be avoided unless it's necessary.
C passes structs by value. What it means is that the function with the second signature would make a copy of the entire LargeStruct in order to pass it to foo. This is not economical in terms of memory use.
What's worse, the allocation of LargeStruct would happen in automatic memory (also known as "on the stack"). Depending on the actual size of your struct, the call may not be possible on some systems, because it would cause stack overflow.
The first approach, on the other hand, passes the struct by pointer. Pointer's size does not depend on the size of LargeStruct.
Since C is passing arguments by value, there are two major points:
In function body, you will receive a copy of the parameter passed in, so in the case of void foo(LargeStruct struct);, you get a copy of the struct, when you modify the members of the struct, it's actually not seen outside, because it's a temporary copy, which is destroyed when the function returns. So if you want to modify a struct, you will have to pass in a pointer to that struct.
Since arguments are copied and if the struct is really large, there is some memory overhead. In this if you don't want to modify the struct, just to minimize the memory overhead, you can pass a const pointer:
foo(const LargeStruct *p);
Writing code in C, never formally learned any of it, using GNU's GSL library, quick fundamental question.
Correct me if I'm wrong, but the way I understand it, when I allocate memory to use for my matrices (using the built-in var = gsl_matrix_alloc(x,x)) and store them in a variable, I'm essentially creating
a pointer, which is simply some address of memory, like:
x01234749162
which POINTS to the first pointer/memory location of my GSL matrix. Tracking when to deallocate the memory of the structure associated with a pointer (again, built-in gsl_matrix_free(x,x,x)) is no problem, and I understand I need to do this before I reassign the pointer of the structure, otherwise I've created a memory leak.
So now to my question, and again, I know this is basic, but hear me out--I couldn't find a particularly straight answer on stackoverflow, mostly because a lot of the answers involve C++ rather than C--how do I free the pointer to the structure itself?
Everyone says "oh, just set it to NULL". Why would that work? That's just changing the memory address that POINTS to the deallocated structure. Does that tell the MMU that that memory location is okay to use now? When I debug my program in XCode, for example, all of the properties of the gsl_matrix structure is successfully deallocated; everything just becomes this garbage string of random hex characters, which is what free'ing memory is supposed to do. But, I can still see the variable name (pointer) while stepping through the debugger... even if I set the variable to NULL. I would interpret that as meaning I did not free the pointer, I just freed the structure and set it to x0000000 (NULL).
Am I doing everything correct, and this is just a feature of XCode, or am I missing something basic?
And I realize that a single pointer to a structure, if the structure is deallocated, could be argued to not be a big deal, but it matters.
Here's some code to try to illustrate my thoughts.
gsl_matrix* my_matrix;
// create single memory address in memory, not pointing to anything yet
my_matrix = gsl_matrix_alloc(5, 5);
// allocates 25 memory spaces for the values that the pointer held by my_matrix
// points too
// Note: so, now there's 26 memory spots allocated to the matrix, excluding other
// properties created along with the my-matrix structure, right?
gsl_matrix_free(my_matrix); // deallocates those 25 spaces the structure had,
// along with other properties that may have been automatically created
free(my_matrix); // SIGBRT error. Is the pointer to the deallocated structure
// still using that one memory address?
my_matrix = NULL; // this doesn't make sense to me.I get that any future referral
// to the my_matrix pointer will just return garbage, and so setting a pointer to
// that can help in debugging, but can the pointer--that is just one memory
// address--be completely deallocated such that in the debugger the variable name
// disappears?
What you miss here is the knowledge of how "local variables" work at the machine level and the concept of "the stack".
The stack is a block of free memory that is allocated for your program when it starts. Suppose, for the sake of a simple example, that your program is allocated a stack of size 1MB. The stack is accompanied with a special register, called "stack pointer", which initially points to the end of the stack (don't ask why not the beginning, historical reasons). Here's how it looks:
[---------- stack memory, all yours for taking ------------]
^
|
Stack pointer
Now suppose your program defines a bunch of variables in the main function, i.e. something like
int main() {
int x;
What this means is that when the main function is invoked at the start of your program, the compiler will generate the following instructions:
sp = sp - 4; // Decrement stack pointer
x_address = sp;
and remember (for purposes of further compilation) that x is now a 4-byte integer located at memory position x_address. Your stack now looks as follows:
[---------- stack memory, all yours for taking --------[-x--]
^
|
Stack pointer
Next, suppose you invoke some function f from within the main. Suppose f defines inside it another variable,
int f() {
char z[8];
Guess what happens now? Before entering f the compiler will perform:
sp = sp - 8;
z_address = sp;
I.e. you'll get:
[---------- stack memory, all yours for taking -[--z----][-x--]
^
|
Stack pointer
If you now invoke another function, the stack pointer will move deeper into the stack, "creating" more space for the local variables. Each time when you exit a function, though, the stack pointer is restored back to where it was before the function was invoked. E.g. after you exit f, your stack will be looking as follows:
[---------- stack memory, all yours for taking -[--z----][-x--]
^
|
Stack pointer
Note that the z array was not essentially freed, it is still there on the stack, but you do not care. Why don't you care? Because the whole stack is automatically deallocated when your application terminates. This is the reason why you do not need to manually deallocate "variables on the stack", i.e. those which are defined as local to your functions and modules. In particular, your my_matrix pointer is just a yet another variable like that.
PS: there is a bit more happening on the stack than I described. In particular, the stack pointer value is stored on the stack before decrementing it, so that it can be restored after exiting the function. In addition, function arguments are often passed by putting them onto the stack. In this sense they look like local variables for purposes of memory management and you don't need to free them.
PPS: In principle, the compiler is free to optimize your code (especially if you compile with the -O flag) and rather than allocate your local variables on the stack it may:
Decide to avoid allocating them at all (e.g. if they turn out to be useless)
Decide to allocate them temporarily in the registers (which are fixed memory slots in the processor that do not need to be freed). This is often done for loop variables (the ones within for (int i = ...)).
.. and well, do whatever else comes to his twisted mind as long as the result does not contradict the semantics.
PPPS: Now you are prepared to learn how buffer overflow works. Go read about it, really, it is an amazing trick. Oh, and, once you're at it, check out the meaning of stack overflow. ;)
Why would 26 memory spots be allocated for a 5x5 matrix? I'd say trust the library-provided gsl_matrix_free function to do the right thing and deallocate the whole structure.
In general, you only need to call free if you called malloc or calloc. Library functions that provide an allocator usually provide a matching deallocator so that you don't have to keep track of the internals.
If the 26th spot you're worried about is the pointer itself (in other words, the memory needed to store the address of the matrix), that space is part of the stack frame for your function, and it is automatically popped when the function returns.
Everyone says "oh, just set it to NULL". Why would that work?
They probably mean that this would fix the problem where you are calling free on a pointer to some data that has already been de-allocated, which is what you are doing here:
gsl_matrix_free(my_matrix); // deallocate
free(my_matrix); // Mistake, BIG PROBLEM: my_matrix points to de-allocated data
It fixes the problem because calling free on a null-ptr is a no op:
gsl_matrix_free(my_matrix); // deallocate
my_matrix = NULL;
free(my_matrix); // Mistake, but no problem
Note: my_matrix itself has automatic storage, so there is no need to de-allocate it manually. Its memory will be reclaimed when it goes out of scope. The only thing that needs to be de-allocated is the memory that was dynamically allocated (and to which my_matrix points.)
I am writing some C code here, and I came across a problem:
I have an array of my custom type. I want to put a size for this array:
typedef struct reg Reg;
Reg myArray[958279];
When I run my program has a segmentation fault.
Then I tried using malloc, which allocates storage space dynamically, and to my surprise it worked:
Reg *myArray = (Reg*)malloc(sizeof(Reg)*958279);
So I assumed there must be some size restriction for array declaration of a static form.
Is there any reference to this fact somewhere? Or am I completely wrong about the my questions?
The array in your first piece of code is, presumably, being allocated on the stack and does not fit. The stack typically has a fixed size and you must not allocate huge objects on the stack. The solution, as you have discovered, is to allocate from the heap.
The following question is in regards to C programming. I am using Microchip C30 compiler (because I know someone will ask)
What is the difference between having a structure which contains several other structures vs a structure which contains several pointers to other structures? Does one make for faster code execution than the other? Does one technique use more or less memory? Does the memory get allocated at the same time in both cases?
If I use the following code does memory automatically get allocated for the subStruct?
// Header file...
typedef struct{
int a;
subStruct * b;
} mainStruct;
typedef struct{
int c;
int d;
}subStruct;
extern mainStruct myMainStruct;
// source file...
mainStruct myMainStruct;
int main(void)
{
//...
{
If you use a pointer, you have to allocate the memory yourself. If you use a substructure, you can allocate the entire thing in one go, either using malloc or on the stack.
What you need depends on your use case:
Pointers will give you smaller struct's
Substructures provide better locality of reference
A pointer may point to either a single struct or the first member in an array of them, while substructures are self-documenting: there's always one of them unless you use an array explicitly
Pointers take up some space, for the pointer itself + overhead from extra memory allocations
And no, it doesn't matter which compiler you use :)
Memory for pointers doesn't get automatically allocated, but when you contain whole structure in your struct, it does.
Also - with pointers you are likely to have fragmented memory - each pointed part of tructure could be in other part of memory.
But with poniters you can share the same substructures across many structs (but this makes changing and deleting them later harder).
Memory for a pointer wouldn't be automatically allocated. You would need to run:
myMainStruct.b=malloc(sizeof(*myMainStruct.b));
In terms of performance, there is likely a small hit to going from one structure to another via the pointer.
As far as speed goes, it varies. Generally, including structs, rather than pointers, will be faster, because the CPU doesn't have to dereference the pointer for every member access. However, if some of the members aren't used very often, and the sub-struct's size is massive, the structure might not fit in the cache and this can slow down your code quite a bit.
Using pointers will use /slightly/ more memory (but only the size of the pointers themselves) than the direct approach.
Usually with pointers to sub-structs you'll allocate the sub-structs separately, but you can write some kind of initialization function which abstracts all the allocation out to "the same time." In your code, memory is allocated for myMainStruct on the stack, but the b member will be garbage. You need to call malloc to allocate heap memory for b, or create a subStruct object on the stack and point myMainStruct.b to it.
What is the difference between having a structure which contains several other structures vs a structure which contains several pointers to other structures?
In the first case what you have is essentially one big structure in contiguous memory. In the "pointers to structures" case your master structure just contains the addresses to the sub-structures which are allocated separately.
Does one make for faster code execution than the other?
The difference should be negligible, but pointers method is will be slightly slower. This is because you must dereference the pointer with each access to the substructure.
Does one technique use more or less memory?
The pointer method uses number_of_pointers * sizeof(void*) more memory. sizeof(void*) will be 4 for 32-bit and 8 for 64-bit.
Does the memory get allocated at the same time in both cases?
No, you need to go through each pointer in your master struct and allocate memory for the sub-structs via malloc().
Conclusion
The pointers add a layer of indirection to the code, which is useful for switching out the sub-structs or having more than one pointer point to the same sub-struct. Having different master-structs pointing to common sub-structs in particular could save quite a bit of memory and allocation time.
I think all malloc(sizeof(structure)) can be replaced this way:
char[sizeof(structure)]
Then when is malloc necessary?
When you don't know how many object of some kind you need (e.g. linked list elements);
when you need to have data structures of size known only at runtime (e.g. strings based on unknown input); this is somewhat mitigated by the introduction of VLAs in C99, but see the next point:
when you know at compile time their size (or you can use VLAs), but it's just too big for the stack (typically a few MBs at most) and it would make no sense to make such thing global (e.g. big vectors to manipulate);
when you need to have an object whose lifetime is different than what automatic variables, which are scope-bound (=>are destroyed when the execution exits from the scope in which they are declared), can have (e.g. data that must be shared between different objects with different lifetimes and deleted when no one uses it anymore).
Notice that it isn't completely impossible to do without dynamic memory allocation (e.g. the whole rockbox project works almost without it), but there are cases in which you actually need to emulate it by using a big static buffer and writing your own allocator.
By the way, in C++ you will never use malloc()/free(), but the operators new and delete.
Related: a case in which trying to work without malloc has proven to be a big mess.
You will use malloc to dynamically allocate memory, either because:
you don't know at compile-time how much memory will be required,
you want to be able to reallocate memory later on (for instance using realloc),
you want to be able to discard the allocated memory earlier than by waiting for its release based on the scope of your variable.
I can see your point. You could think you could always using a declarative syntax for all of these, even using variables to declare the size of your memory spaces, but that would:
be non-standard,
give you less control,
possibly use more memory as you will need to do copies instead of re-allocating.
You will probably get to understand this in time, don't worry.
Also, you should try to learn more about the memory model. You don't use the same memory spaces when using a dynamic allocation and when using a static allocation.
For first pointers, visit:
Dynamic Memory Allocation
Static Memory Allocation
Stack vs Heap
Stack vs Heap?
How C Programming Works - Dynamic Data Structures
Friendly advice: I don't know if you develop C on *NIX or Windows, but in any case if you use gcc, I recommend using the following compilation flags when you teach yourself:
-Wall -ansi -pedantic -Wstrict-prototypes
You should read about dynamic memory allocation. You obviously don't know what it is.
The main difference between the two is that memory allocated with malloc() exists until you say so. Static memory such as char buff[10]; only exists in the function scope.
malloc is a dynamic memory allocator which helps u up to assign memory to ur variables according to ur need and therefore reduces the loss of memory.It is also supported by realloc() function through which u can edit the memory required which u have defined earlier through malloc() or calloc(). So in short we can say that malloc() can be used for managing the memory space and making use of the necessary memory without wasting it.
You never should do this the way you are proposing. Others already told you about the difference of allocating storage on the heap versus allocation on the function stack. But if and when you are allocating on the stack you should just declare your variable:
structure A = { /* initialize correctly */ };
There is no sense or point in doing that as an (basically) untyped char array. If you also need the address of that beast, well, take the address of with &A.
When you don't know how much memory to allocate at compile time. Take a very simple program, where you need to store the numbers entered by the user in linked list. Here you dont know how many numbers will be entered by the user. So as user enters a number you will create a node for it using malloc and store it in the linked list.
If you use char[sizeof(structure)] instead of malloc, then I think no dynamic memory allocation is done.
Besides the fact that your char[] method cannot resize or determine the size at runtime, your array might not be properly aligned for the type of structure you want to use it for. This can result in undefined behaviour.