This question already has an answer here:
Segmentation Fault, large arrays
(1 answer)
Closed 4 years ago.
So I'm trying to declare a struct of size 19,000, however when I compile this I get Seg fault, core dumped. I think I have to use malloc but I can't
figure out whats the best syntax to use considering I'm not using pointers!!
Struct people{
char name[100]
char secondname[100]
}
int main(){
struct people p1[19000]
}
Above is the code corresponding to my problem
Any Help would be greatly appreciated
Your struct array requires about 3.8Mb of stack space, while on most modern Desktop platforms, the typical default process or thread stack is perhaps a couple of Mb.
You can either dynamically or statically allocate the memory. Static allocation if simplest and appropriate is the lifetime of the array is the duration of program execution, and the required size is known a priori.
int main()
{
static struct people p1[19000] ;
}
Dynamic allocation is a possible solution, but since malloc() returns a pointer to the allocated memory, you are necessarily using pointers; but array access notation can be used, so your exposure ot pointers will be minimal:
int main()
{
struct people* p1 = malloc(sizeof(struct people) *19000 ) ;
...
// Access to elements of the dynamically allocated array
// is identical to that of the statically allocated array.
printf( "%s", p1[0].name ) ;
}
An advantage of dynamic allocation is that you can avoid allocating an arbitrarily large space, and create records on demand, storing pointers in a dynamically resizing array (using realloc() for example), or some suitable container data structure such as a linked list. But perhaps that is too advanced for where you are at at the moment.
struct people p1[19000] tries to create 19000 structs of 100+100 bytes in automatic stack memory. Normal stack memory is not large enough and you get a stack overflow or some other error.
In C, there is much more heap memory available, but the programmer has to do the heap memory management
To allocate the array in heap memory, you can use for instance:
int main() {
struct people *p1 = malloc(19000 * sizeof(struct people));
// you can now access p1 using array brackets as follows:
// strcpy(p1[0].name, "name");
// strcpy(p1[0].secondname, "secondname");
// printf("name: %s, secondname: %s\n", p1[0].name, p1[0].secondname);
}
Related
So I'm looking at a solution to some coding interview type questions, and there's an array inside a struct
#define MAX_SIZE 1000000
typedef struct _heap {
int data[MAX_SIZE];
int heap_size;
}heap;
heap* init(heap* h) {
h = (heap*)malloc(sizeof(heap));
h->heap_size = 0;
return h;
}
This heap struct is later created like so
heap* max_heap = NULL;
max_heap = init(max_heap);
First of all, I'd wish this was written in C++ style than C, but secondly if I'm just conscerned about the array, I'm assuming it is equivalent to solely analyze the array portion by changing the code like this
int* data = NULL;
data = (int*)malloc(1000000 * sizeof(int));
Now in that case, is there any problems with declaring the array with the max size if you are probably just using a little bit of it?
I guess this boils down to the question of when an array is created in the heap, how does the system block out that portion of the memory? In which case does the system prevent you from accessing memory that is part of the array? I wouldn't want a giant array holding up space if I'm not using much of it.
is there any problems with declaring the array with the max size if you are probably just using a little bit of it?
Yes. The larger the allocation size the greater the risk of an out-of-memory error. If not here, elsewhere in code.
Yet some memory allocation systems handle this well as real memory allocations do not immediately occur, but later when needed.
I guess this boils down to the question of when an array is created in the heap, how does the system block out that portion of the memory?
That is an implementation defined issue not defined by C. It might happen immediately or deferred.
For maximum portability, code would take a more conservative approach and allocate large memory chunks only as needed, rather than rely on physical allocation occurring in a delayed fashion.
Alternative
In C, consider a struct with a flexible member array.
typedef struct _heap {
size_t heap_size;
int data[];
} heap;
I've recently started learning C and currently I'm working on a project which involves implementing a struct with two variables and I don't really know how to apparoach this.
The gist of it is I need to implement a struct which contains two variables, a pointer to an int array AND an int value which indicates the number of elements conatained within the array. The size of the array is declared upon the invocation of the constructor and is dependent on the input.
For the constructor I'm using a different function which recieves a string
as input which is encoded into a decimal code. Also this function recieves another input
which is a pointer to an int array (the pointer defined in the struct) and the problem is I'm using the malloc() function to allocate memory for it but I dont really understand how and when to use the free() function properly.
So, the questions are:
When am I supposed to free the allocated memory? (assuming I need this struct for later use throughout the program's running time)
What are the best ways to avoid memory leaks? What should you look out for?
It's unclear whether you're expected to manage the memory of the array inside, but this is functionally the setup you need for allocating the containing structure.
#include <malloc.h>
#include <stdio.h>
struct my_struct {
size_t num_entries;
int *array;
};
int main() {
struct my_struct *storage = malloc(sizeof(struct my_struct));
storage->num_entries = 4;
storage->array = malloc(sizeof(int) * storage->num_entries);
storage->array[0] = 1;
storage->array[3] = 2;
printf("allocated %ld entries\n", storage->num_entries);
printf("entry #4 (index=3): %d\n", storage->array[3]);
free(storage->array); /* MUST be first! */
free(storage);
storage = 0; /* safety to ensure you can't read the freed memory later */
}
if you're responsible for freeing the internal storage array, then you must free it first before freeing the containing memory.
The biggest key to memory management: only one part of the code at any time "owns" the memory in the pointer and is responsible for freeing it or passing it to something else that will.
If you want to allocate an array of struct you can do it statically by declaring something like
struct myStruct myStructArray[100];
or dinamically with something like
struct myStruct *myStructArray = calloc(100, sizeof(struct myStruct) );
but in this case you are responsible for freeing the memory.
In many applications and samples I found a mixed approach:
struct wrapperStruct
{
int myInt;
struct myStruct myStructArray[1];
};
Then the allocation is performed like this
int n = 100;
size_t memory_size = sizeof(struct wrapperStruct) + (n - 1) * sizeof(struct myStruct);
struct wrapperStruct *wrapperStruct_p = calloc(1, memory_size);
So (if I understood correctly) since the array is the last member of the struct and the field of a struct respect the same position in memory then you are "extending" the single entry array myStructArray with 99 entries.
This allow you to safety write something like wrapperStruct_p.myStructArray[44] without causing a buffer overflow and without having to create a dynamic allocated array of struct and then take care of the memory disposal at the end. So the alternative approach would be:
struct wrapperStruct
{
int myInt;
struct myStruct *myStructArray;
};
struct wrapperStruct *wrapperStruct_p = calloc(1, sizeof(struct wrapperStruct) );
wrapperStruct_p.myStructArray = calloc(100, sizeof(struct myStruct) )
The question is what happens when you try to free the wrapperStruct_p variable ?
Are you causing a memory leak ?
Is the C memory management able to understand that the array of struct is made of 100 entries and not 1 ?
What are the benefits of the first approach apart from not having to free the pointer inside the struct ?
The question is what happens when you try to free the wrapperStruct_p
variable ?
Are you causing a memory leak ?
Most likely, but not necessary. The memory for the inner dynamic array is not freed, but you could still free it later if you saved the pointer address to some other variable.
Is the C memory management able to understand that the array of struct is made of 100 entries and not 1 ?
"C memory management" takes care of stack and heap allocations (the latter using systemcalls so maybe it's not really a "C memory management"), it doesn't do much else other than provide syntactic sugar on top of assembler (unlike garbage collected languages like Java or other).
C itself doesn't care about how many entries are somewhere and what part of memory you access (SEGFAULTS are the OS response to memory access violations)
What are the benefits of the first approach apart from not having to
free the pointer inside the struct ?
If by "first approach" you mean stack allocated array, then it's mainly the fact that you do not need to allocate anything and the stack does it for you (drawback being that it stays allocated in the declared scope and you can't free up or increase the array space) then the constant allocation speed and assurance you'll get your 100 array items no matter the OS response (many realtime applications require maximum response times, therefore a heap allocation can be a really big slowdown causing problems).
If by "first approach" you mean using the wrapper struct, then I do not see any benefits other than the one you already stated.
I'd even suggest you not advocate/use this approach, since it is a really confusing technique that doesn't serve noticeable benefits (plus it allocates 1 space even though it may not be even used, but that's a detail)
The main goal is to write code that is easily understandable by other people. Machines and compilers can nowadays do wonders with code, so unless you are a compiler designer, standard library developer or machine level programmer for embedded systems, you should write simple to understand code.
This question already has answers here:
How does free know how much to free?
(11 answers)
Closed 9 years ago.
we allocate memory dynamically in C using malloc() and we receive a pointer to a location in the heap.
now we use free() to deallocate the memory, passing the same pointer value as its argumnet.
the Question now is how does free() know how much to deallocate.. considering the fact that we can always resize the memory block allocated by malloc().
is there anything related to Hash Tables here?
A typical implementation will store information just before the address returned by malloc. That information will include the information that realloc or free needs to know to do their work, but the details of what exactly is stored there depends on the implementation.
The original technique was to allocate a slightly larger block and store the size at the beginning, a part the application didn't see. The extra space holds a size and possibly links to thread the free blocks together for reuse.
There are certain issues with those tricks, however, such as poor cache and memory management behavior. Using memory right in the block tends to page things in unnecessarily and also create dirty pages which complicate sharing and copy-on-write.
So a more advanced technique is to keep a separate directory. Exotic approaches have also been developed where areas of memory use the same power-of-two sizes.
In general, the answer is: a separate data structure is allocated to keep state.
A simplist implementation is the one in the famous K&R C Bible,page 186 - 188.
The memory block we get actually is more (a struct head's or a union head's size) than we apply for.The struct may be like this:
typedef long Align;
union header
{
struct
{
union header* ptr; // next block
unsigned size; // size of this block , times of head size
}s;
Align x;
};
A figure to demonstrate it:
When we call the free function, the behaviour may be like this:
void free(void* ptr)
{
Header *bp, *p;
bp = (Header *)ptr - 1;
/* ..... */
/*return the memory to the linked list */
}
In visual studio, we have two models: release version and debug version,we could even use
the head to store debug message to make debug easier.The header in debug version is called _CrtMemBlockHeader, the definition is as below :
typedef struct _CrtMemBlockHeader
{
struct _CrtMemBlockHeader * pBlockHeaderNext;
struct _CrtMemBlockHeader * pBlockHeaderPrev;
char * szFileName;
int nLine;
size_t nDataSize;
int nBlockUse;
long lRequest;
unsigned char gap[nNoMansLandSize];
} _CrtMemBlockHeader;
Then the memory lalout is:
A memory manager uses tables to store additional data based on a pointer, sometimes right before the pointer, sometimes elsewhere. With C being very simple, the data is most likely pointer-2 or pointer-4, as int or long type. The correct details depend on the compiler.
When we use malloc ,a block will get reserve whose size will be littile more than what we have requested and in return to this malloc we get a pointer to start of this block.
AS i told you size of this block will be littile more than what exactly you needed.This extra space will be used to keep actual requested size of block,pointer to next free block and some data which checks "if you trying to access more than allocated block".
So whenever we call free using the pointer we want to deallocate, this free will search for the extra information given in the block space, Where it gets final size to deallocate.
I am new at C language and I need to create a queue and I donĀ“t if I need to use a malloc (memory allocation) and how to use it. I had run add, remove, size and isempty without malloc and it worked.
void e1_init(e1queue_t* q){
q->head = 0;
q->tail = sizeof(q->queue)/sizeof(int)-1;
q->size=0;
}
Thanks.
In C, there are two kinds of memory:
The Stack
The Heap
Stack memory is rather limited and is used for automatic variables in functions, processing overhead, things like that.
When you need a larger chunk of memory, you need to get it from the heap.
Not an exact duplicate of this answer, but this seems to be a good description:
What and where are the stack and heap?
C dynamic memory allocation refers to performing dynamic memory allocation in the C programming language via a group of functions in the C standard library, namely malloc, realloc, calloc and free
Syntax:
#include <stdlib.h>
Description:
The function malloc() returns a pointer to a chunk of memory of size size, or NULL if there is an error. The memory pointed to will be on the heap, not the stack, so make sure to free it when you are done with it.
Example:
typedef struct data_type {
int age;
char name[20];
} data;
data *bob;
bob = (data*) malloc( sizeof(data) );
if( bob != NULL ) {
bob->age = 22;
strcpy( bob->name, "Robert" );
printf( "%s is %d years old\n", bob->name, bob->age );
}
free( bob );
Good Read C dynamic memory allocation
There are many reasons to use malloc() function.
malloc() is used to dynamically allocate memory for variables.
why?
There can be many reasons to allocate memory dynamically. For instance if the size of a certain object/variable isn't known at COMPILE time, and there might be a reason to increase it later on, then its required to increase the memory requirement. and this is where malloc comes in.
malloc() is used to initialize POINTERS
why?
POINTERS that aren't initialized point to a random location. This location may be in-accessible and might crash the program. When malloc is used, it increases the heap storage and points the randomly initialized pointer to a "sane" location, which can be read/written to.
also, pointers initialized with malloc can be resized using realloc() method. This makes memory management flexible(and error prone as well)