Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Consider the below code segment:
void f() {
int arr[10];
arr = malloc(sizeof(int) * 100);
for (int i = 0 ; i < 100 ; i++) {
printf("%d ", arr[i]);
}
puts("");
free(arr);
}
Will the original arr[10] stack memory be freed when the function f returns? (Or is this a stack memory leak?)
You cannot do
arr = malloc(sizeof(int) * 100);
like you've done (tried to do) in your code snippet. arr is array type and assignment is not permitted on that.
Subsequently, maybe worthy to mention, calling free() on a non-dynamically allocated pointer invokes undefined behavior.
FWIW, "leak" comes into picture for the memory allocated by the dynamic memory allocation (generally, heap). For variables allocated in "stack" area (by compiler) need not to managed (for de-allocation or free -ing) from your program.
int arr[10]; this array is already allocated from stack;
to allocate array dynamically declare it as a pointer
int *arr;
dynamic allocation will not be automatically freed, use free or similar to free it;
When you declare the array arr, you are already assigning space (on your function stack) to it. It doesn't make sense to make the malloc'd memory (which gets allocated on the heap) assigned to that array.You are invoking compile error doing that. You should have used a pointer instead of declaring that array. A pointer will grab and store that malloc'd space for you.
Related
The code is as follow :
#include <stdlib.h>
int num = 3; // Static external variable
int *ptr = #
int main(void)
{
int num2 = 4; // Automatic variable
int *ptr2 = &num2;
free(ptr); //Free static variable
free(ptr2); //Free automatic variable
return 0;
}
I try to compile the above code and it works, I'm curious does the free() function able to free both the static variable and also automatic variable? Or basically it does nothing?
Calling free() on a pointer not returned by memory allocating functions(malloc,calloc etc) causes Undefined Behavior.
Your code has an Undefined Behavior, So the compiler does not need to give you any diagnostic of it and it can show any behavior, it might work, or crash, or literally do anything.
Just avoid writing code which causes an Undefined Behavior is the only solution.
You shouldn't do that. free is only used for memory dynamically allocated from heap by malloc family of functions.
Memory for num is statically allocated in data segment and can't be released. Memory for num2 is allocated in the main's call stack frame and will be released as soon as main returns.
What actually happens depend on implementation of free. There are usually specific data structures maintained in heap to help malloc/free track the allocated and free memory areas. free expects these data structures to be somewhere around the place its argument points to. An when you pass it a pointer which doesn't point to a malloc-allocated heap area, it'll consider garbage data as some useful information and do some strange things. And you're lucky if the result is just an immediate program crash.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Consider the following C code:
#include <stdio.h>
#include <stdlib.h>
int main() {
int arrSize;
scanf("%d", &arrSize);
printf("%d\n",arrSize);
int *dynArr = (int *)malloc(sizeof(int)*arrSize);
int arr1[arrSize];
return 0;
}
In the code above, arrSize is size of an array taken from the user input. I want to know if the following observations are correct:
dynArr is a dynamic array which is allocated in the memory during runtime on heap. Size of dynArr can be modified using realloc function.
arr1 is also allocated in the memory during runtime but is not dynamic (i.e. their size cannot be modified) and it is allocated on Stack.
i) dynArr is a dynamic array which is allocated memory during runtime
from heap section. Size of dynArr can be modified using realloc
function.
Yes, if realloc can find a big enough block. Although technically, the pointer isn't an array. It points to the first element of an array.
ii). arr1 is also allocated memory during runtime but is not dynamic
i.e. their size cannot be modified. Memory is allocated from the stack
or data section. (Not sure from which section heap or stack/data the
memory is allocated and why).
The size of the array is dynamic, it's lifetime isn't. It will be reclaimed automatically the moment main returns. Variable length arrays are usually allocated on the call stack. And yes, you cannot change it's size once you declared it.
If you are now wondering when to use one over the other there are a few points to consider:
The memory reserved for the call stack is limited (more so than the heap by far). It's easy to overflow if you declare a huge VLA on it.
The memory returned from malloc and its kin can outlive the stack frame where it was allocated.
Generally, allocating VLA's can be faster than allocating memory with malloc. One is a simple progression of the stack frame pointer, while the other involves the heap's memory allocator and its logic.
dynArr is a dynamic array which is allocated memory during runtime from heap section. Size of dynArr can be modified using realloc function.
No, dynArr is a pointer, which is initialized using the returned pointer by malloc(). Remembers, arrays are not pointers and vice-versa. IN some cases, an array name decays to a pointer to the first element of the array, but that does not make both the same.
size of dynArr is the size of the pointer, not the size of the memory location it points to. Using the correct words, in can be represented as, the size of memory it points to can be changed using realloc().
arr1 is also allocated memory during runtime but is not dynamic i.e. their size cannot be modified. Memory is allocated from the stack or data section. (Not sure from which section heap or stack/data the memory is allocated and why).
This is called variable length array. Other points are correct.
Quoting C11, chapter ยง6.7.6.2
If the size is an expression that is not an integer constant expression: if it occurs in a
declaration at function prototype scope, it is treated as if it were replaced by *; otherwise,
each time it is evaluated it shall have a value greater than zero. The size of each instance
of a variable length array type does not change during its lifetime.
It allocates memory from free memory store. Now there is nothing called heap and stack in memory in case of C..it is something logically we consider in case of C.(In implementation of C)]
Only thing we are bothered about whether we need something which you want to be alive even if the scope of where it is declared ends or not.
For heap it is the case .. for stack it is not.
In your case
int arr1[arrSize]; is allocated on the same frame on which this main function local variables are stored.
Dynamic allocation
You control the exact size and the lifetime of these memory
locations. If you don't free it, you'll run into memory leaks, which
may cause your application to crash, since it, at some point cannot
allocation more memory. (dynArr)
Actually...
Heap
The heap is a region of your computer's memory that is not managed
automatically for you, and is not as tightly managed by the CPU. It is
a more free-floating region of memory (and is larger). To allocate
memory on the heap, you must use malloc() or calloc(), which are
built-in C functions.
Once you have allocated memory on the heap, you
are responsible for using free() to deallocate that memory once you
don't need it any more. If you fail to do this, your program will have
what is known as a memory leak. That is, memory on the heap will still
be set aside (and won't be available to other processes).
Stack
It's a special region of your computer's memory that stores temporary
variables created by each function (including the main() function).
The stack is a "LIFO" (last in, first out) data structure, that is
managed and optimized by the CPU quite closely. Every time a function
declares a new variable, it is "pushed" onto the stack. Then every
time a function exits, all of the variables pushed onto the stack by
that function, are freed (that is to say, they are deleted). Once a
stack variable is freed, that region of memory becomes available for
other stack variables.
Resources
Link 1
Actually, the variable length array are not allowed in Google C++ Style Guide. It has a natural-looking syntax and it's efficient, however, because of they allocate a data-dependent amount of stack space, it can trigger serious and mysterious memory overwriting bugs:
Sometimes "It ran fine on my machine, but dies mysteriously in production".
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Would you like to help me to understand the mechanism of "pointers" in C:
How does the program identify the end of an array, which was dynamically allocated and pointed at by a pointer (example: montext1)? Where are these arrays stored in RAM (probably not in data, not in stack, perhaps in the heap)?
A pointer is defined by a type and a size: how is this implemented in RAM for a dynamic allocation like in the example below?
#include <stdio.h>
char * gettext()
{
char *text;
printf("Text:");
scanf("%s", &text);
printf("\n");
return text;
}
int main()
{
char *montext1 = gettext();
char *montext2 = gettext();
}
Your program is very wrong, and has undefined behavior. So it's not a very good starting point for discussion.
There is no "dynamic allocation" in your program, only chaotic overwriting of random memory.
It should use heap allocation, i.e.:
char * gettext(void)
{
char *s;
printf("Text:");
fflush(stdout);
if((s = malloc(256)) != NULL)
{
if(fgets(s, 256, stdin) == NULL)
{
free(s);
s = NULL;
}
}
return s;
}
The caller must free() the returned string, and check for NULL before printing it.
The problem here is the CPU does not know the end of the data pointed to by a pointer. For the CPU it's just raw bytes in the memory which can be either application bytes or data entered by the user. However the compiled C code via the C std library know the string (char*) is supposed to end with a zero byte. That's how it knows where the end is.
But, in the gettext method: you need to allocate some memory too, via malloc (calloc), because in it's current stage your application is writing into memory which is not owned by it. And of course, the caller of gettext needs to free the memory.
And finally: a pointer is just an address in the memory, it points to some bytes. It is the role of the application to interpret those bytes in the proper way, such as identify zero terminated strings.
How does the program identify the end of an array, which was dynamically allocated and pointed at by a pointer
This is handled internally by the dynamic memory allocation library routines and it is handled differently on every implementation. The actual code could be in stdlib or it could be in an OS API. So how it is done depends on compiler and OS both.
Where are these arrays stored in RAM
If they were dynamically allocated, they were stored on the heap.
A pointer is defined by a type and a size
No, a pointer is a type, end of story.
how is this implemented in RAM for a dynamic allocation like in the example below
You linked no example containing dynamic allocation. The code you posted is nonsense code. It attempts to copy data into the address where you allocated a pointer. This doesn't make any sense, so the program will crash and burn.
If you rewrite the program so that scanf("%s", &text); is replaced by scanf("%s", text);, then you attempt to copy data into an uninitialized pointer's address, which is random. This is undefined behavior and will also cause your program to crash and burn.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Sorry, I'm a bit of a newbie to C and was wondering how you could create an array whose size is not known at compile time before the C99 standard was introduced.
It's very easy. For example, if you want to create a variable length 1D int array, do the following. First, declare a pointer to type int:
int *pInt;
Next, allocate memory for it. You should know how many elements you will need (NUM_INTS):
pInt = malloc(NUM_INTS * sizeof(*pInt));
Don't forget to free your dynamically allocated array to prevent memory leaks:
free(pInt);
Use malloc function from stdlib.h to create a dynamic array object.
the ordinary way would be to allocate the data on the heap
#include <stdlib.h>
void myfun(unsigned int n) {
mytype_t*array = (mytype_t*)malloc(sizeof(mytype_t) * n);
// ... do something with the array
free(array);
}
you could also allocate on the stack (so you don't need to free manually):
#include <alloca.h>
void myfun(unsigned int n) {
mytype_t*array = (mytype_t*)alloca(sizeof(mytype_t) * n);
// ... do something with the array
}
You can do this by dynamic memory allocation. Use malloc function.
malloc or calloc
YourType* ptr = malloc(sizeof(YourType)*NumberOfItemsYouNeed)
This question already has answers here:
Is an array name a pointer?
(8 answers)
Closed 9 years ago.
I am really confused in arrays and pointers.
Please tell me What is difference between following two codes?
int main()
{
int i,*p;
for(i=0;i<5;i++)
{
p[i]=i;
printf("%d",p[i]);
}
return 0;
}
int main()
{
int i,p[5];
for(i=0;i<5;i++)
{
p[i]=i;
printf("%d",p[i]);
}
return 0;
}
First one results in undefined behaviour.
For not having UB you need to allocate memory using either malloc or calloc.
Allocating memory will store the data in heap. After you done with your task , you need to free the allocated memory also.
Second one do not result in UB. it stores the array data in stack and not on heap.
Memory is automatically freed from stack once the scope is over.
In first p points to garbage location (not-allocated), and I'm pretty sure that in the way you are using it will generate a segmentation fault. You should allocate memory first, before using it, like:
p = malloc(5 * sizeof(int))
Second is allocated on stack and have the lifetime of the scope it is declared in.