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.
Related
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
Switching from a OO language (C#), I would like to know what is the best way to declare a struct array that has application lifetime in C. After 1h struggle (and research for ex. about why not to use typedef, why to repeat struct later, etc.), this code is working:
// declaration
struct server {
char* name;
char* ip_address;
int port;
} server;
struct server *servers; // declaring struct server[] servers; does not work
Then using like this in a function, working as well (after multiple experiments with & and *...):
// nb_servers is known from previous calculation
servers = malloc(nb_servers * sizeof(struct server));
// later in the same function
free(servers);
Questions
Why does declaring the struct array with [] not work? Question actually is, is it also possible to declare an array with '[]' (unknown size) and then dynamically initialize it later with malloc and if yes, what is the syntax to do it? Pure syntax question independent of differences in how memory is managed.
If I free(servers) I can no longer use the values after that. But if I don't, if this function gets called multiple times, will the value of this variable simply be overwritten by the result of the new call? Will not freeing servers cause a memory leak?
Hope it is clear, I'm 100% new to C.
is it also possible to declare an array with '[]' (unknown size) and then dynamically initialize it later with malloc?
No. An array must have a knowable size when it is declared. This can be done by explicitly giving it a size in the brackets, or it can be inferred by its initializer. Once its size is set, it will remain that size for its lifetime. malloc, in the strictest sense, doesn't create an "array", but rather returns a pointer to a segment of memory that can be indexed similarly to an array syntactically, but is not truly an array in the same sense as an object declared with [].
Will not freeing servers cause a memory leak?
Yes, you will have a memory leak if you do not free servers before mallocing more memory for it without freeing. If you simply need to resize the array without ditching the data, you can use realloc.
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 this maybe a really dumb question, but i just want to be clarified. Thanks in advance! I'm not sure if an array of structure declared as a local variable inside a function gets allocated in the stack. Doesn't?
It does; anything you declare without allocating yourself (e.g. by calling malloc) or declare static (as Fernando says) is allocated on the stack. Structures are just a way of grouping together multiple variables; they still have a fixed size (the total size of their elements, possibly plus some padding), and accessing a struct's field just means pulling the appropriate bytes from somewhere within the struct
Unless you use malloc() (as #Michael Mrozek said) or declare it with the "static" modifier, it's allocated in the stack.
Yes, an array declared in a function scope as an auto variable will be allocated from the stack. You want to be judicious when doing so as you can never be certain from the calling context if there will be enough stack space to succeed. Even though Windows by default creates 1MB stacks for threads and Linux creates 8MB stacks by default, you can still have a problem if you create large arrays of structures. In some operating systems the thread stack may be as little as a few kB.
I tend to keep function scope auto variables limited to simple scalar types and put large abstract types and arrays on the heap.
It is just like other variable:
void function()
{
struct my_struct a; // in the stack;
struct my_struct *b = malloc(sizeof(struct my_strcut)); // not in the stack;
static struct my_struct c; // not in the stack;
}
What am I doing wrong?
While using Eclipse on a Mac (2GB RAM) I have encountered the following problem:
Whenever I try to create an array which exceeds 8384896 bytes, I get segmentation faults. The following program would execute:
#include <stdio.h>
main()
{
double x[1048112];
printf("sizeof(x) = %li", sizeof(x));
}
and the output would be (as expected):
sizeof(x) = 8384896
But increasing the number of elements in x or creating additional variables in main() would result in an unexecutable program and segfaults. It looks like I'm hitting some memory limit and I don't understand why this is happening.
I'd be really grateful if anyone could explain this to me, or maybe provide some sort of solution to my problem.
This is a stack overflow due to excessively large stack variables.
If you really need to allocate something that large, you can do so on the heap using malloc:
double *x = malloc(1048112 * sizeof(double));
Note that with this change, sizeof(x) no longer returns the size of the array, it returns the size of double *. If you need to know how large your array is, you'll need to keep track of that on your own.
And, just for completeness, when you are done with the data, you will need to call free, otherwise you'll have one heck of a memory leak:
free(x);
A process on OS X is limited, by default to 8MB stack (try running ulimit -s from the command line).
One option is to try and increase the stack size by using something like ulimit -s 65536. This should affect all new processes ran from the current shell session.
A better option is to allocate the array on the heap:
double *x = (double*)malloc(9999999)
And when you are finished with the array, don't forget to deallocate it using: free(x)
EDIT: try this reference for information on how to use the linker to increase maximum stack size on OS X. Again, the preferred option is just to allocate large arrays on the heap. Easier and more portable.
Other solutions to the problem include using a static array:
static double x[1234567];
in your function, or using a global variable outside the function. If the global array is declared static it won't be visible outside the file it is compiled from.
Either way, the array will not be renewed each time you call the routine, so you won't get a "fresh start" each time you call it but the same old data as before.
Yup, you are hitting a memory limit ... specifically, you are Stack Overflowing. So what should you do ? Allocate memory on the heap ... as so:
double *x=malloc(1048112*sizeof(double));
The malloc based solution is right, but this one will save you the trouble of having to track memory yourself:
#include <stdio.h>
static double x[1048112];
main()
{
printf("sizeof(x) = %li", sizeof(x));
}
Variables that are declared static outside of the function body are not allocated from the stack, and their visibility is limited to the file they're defined in.
You can either increase the amount of allowed space on the stack through linker settings, or preferably start using dynamic memory.
As a side note: In my experience, in some cases the questions of that nature ("why does my huge automatic array cause a crash") are rooted in the beginners' misunderstanding of the physical nature of an array object. More than once I encountered people that firmly believed that an array physically consists of a "pointer" that points to an additional block of memory for the actual elements. They also believed that an automatic array occupies only a tiny amount of stack memory (for the alleged "pointer"), while the large element block is allocated elsewhere, not in the stack. This might be one of the possible reasons why people (even those who are perfectly aware of the "limitedness" of stack space) see no issues with defining large automatic arrays.
Just to you to know this limit in windows is 1 mb
this code work
void myfunction()
{
static char yes[1100000]//allocated in the heap
}
this code donĀ“t work
void myfunction()
{
char yes[1100000]//allocated in the stack
}