My Doubt is regarding only memory allocation so don't think about program output
#include<stdio.h>
int main(){
for(int i=0;i<20;i++){
char *str=malloc(sizeof(char)*6); //assuming length of each string is 6
scanf("%s",str);
insertinlinkedlist(str);
}
}
whenever i allocate memory here as shown above only the base address of char array will pass to linked list,and that is the memory block allocated for char array is inside main only and i am storing the base address of that array in str which is local to main and is passed to insetinlinkedlist
I want to ask whenever memory is allocated inside loop than why the number of
memory blocks(no of char arrays declared ) are created equal to n (number of time loop runs) since variable name is same we should be directed to same memory location
Note I have checked in compiler by running the loop all the times when loop runs memory the value of str is different
is The above method is correct of allocating memory through loop and through same variable "Is the method ensures that every time we allocate memory in above manner their will be no conflicts while memory allocation and every time we will get the address of unique memory block"
Now above doubt also creates a doubt in my mind
That if we do something like that
int main(){
for(int i=0;i<n;i++){
array[50];
}
}
then it will also create 50 array inside stack frame
malloc returns a pointer to the first allocated byte. Internally it keeps track of how much memory was allocated so it knows how much to free (you do need to insert calls to free() or you'll leak memory, by the way). Usually, it does this by allocating a little bit of memory before the pointer it gives you and storing the length there, however it isn't required to do it that way.
The memory allocated by malloc is not tied to main in any way. Currently main is the only function whose local variables have a pointer to that memory, but you could pass the pointer to another function, and that function would also be able to access the memory. Additionally, when the function that called malloc returns, that memory will remain allocated unless manually freed.
The variable name doesn't matter. A pointer is (to first approximation) just a number. Much like how running int a = 42; a = 20; is permitted and replaces the previous value of a with a new one, int *p = malloc(n); p = malloc(n); will first assign the pointer returned by the first malloc call to p, then will replace it with the return value of the second call. You can also have multiple pointers that point to the same address:
int *a = malloc(42);
int *b = malloc(42);
int *c = a;
a = malloc(42);
At the end of that code, c will be set to the value returned by the first malloc call, and a will have the value returned by the last malloc call. Just like if you'd done:
//assume here that f() returns a different value each time
//it's called, like malloc does
int a = f();
int b = f();
int c = a;
a = f();
As for the second part of your question:
for(int i=0;i<n;i++){
int array[50];
}
The above code will create an array with enough space for 50 ints inside the current stack frame. It will be local to the block within the for loop, and won't persist between iterations, so it won't create n separate copies of the array. Since arrays declared this way are part of the local stack frame, you don't need to manually free them; they will cease to exist when you exit that block. But you could pass a pointer to that array to another function, and it would be valid as long as you haven't exited the block. So the following code...
int sum(int *arr, size_t n) {
int count = 0;
for (size_t i = 0; i < n; i++) {
count += arr[i];
}
return count;
}
for(int i=0;i<n;i++){
int array[50];
printf("%d\n", sum(array, 50));
}
...would be legal (from a memory-management perspective, anyway; you never initialize the array, so the result of the sum call is not defined).
As a minor side note, sizeof(char) is defined to be 1. You can just say malloc(6) in this case. sizeof is necessary when allocating an array of a larger type.
Related
How can I allocate memory on the stack and have it point to different memory addresses so I can use it later? For example. this code:
for (int i = 0; i < 5; i++) {
int nums[5];
nums[0] = 1;
printf("%p\n", &nums[0]);
}
Will print out the same address every time. How can I write memory to stack (not the heap, no malloc) and have it not overwrite something else that's on the stack already.
You could use alloca to allocate a different array from the runtime stack for each iteration in the loop. The array contents will remain valid until you exit the function:
#include <stdlib.h>
#include <stdio.h>
void function() {
for (int i = 0; i < 5; i++) {
int *nums = alloca(5 * sizeof(*nums));
nums[0] = 1;
printf("%p\n", (void *)nums);
/* store the value of `num` so the array can be used elsewhere.
* the arrays must only be used before `function` returns to its caller.
*/
...
}
/* no need to free the arrays */
}
Note however that alloca() is not part of the C Standard and might not be available on all architectures. There are further restrictions on how it can be used, see the documentation for your system.
I believe you are looking for:
a way to control how memory is being allocated on the stack, at least in the context of not overwriting already-used memory
Of course, that's taken care by the OS! The low level system calls will make sure that a newly created automatic variable will not be written upon an already used memory block.
In your example:
for (int i = 0; i < 5; i++) {
int nums[5];
...
}
this is not the case, since nums will go out of scope, when the i-th iteration of the for loop terminates.
As a result, the memory block nums was stored into during the first iteration, will be marked as free when the second iteration initiates, which means that when nums of the first iteration is going to be allocated in the stack, it will not be aware of any existence of the nums of the first iteration, since that has gone already out of scope - it doesn't exist!
I'm currently studying variable length array and automatic storage.
I have the following code that allocate memory for an variable length array myArray inside function vla, and return a pointer to the variable length array from the function.
#include <stdio.h>
int * vla(int n){
int myArray[n];
myArray[0] = 10;
myArray[1] = 11;
int * pointerToInt = myArray;
return pointerToInt;
}
int main(void){
int * pointerToInt = vla(10);
printf("%d, %d", pointerToInt[0], pointerToInt[1]); // prints 10, 11
return 0;
}
I thought that variable length array belong to the automatic storage class (i.e. the memory for the variable length array will be allocated when we enter the function containing the variable length array, and the memory is automatically deallocated after the function exit)
So according to this logic, the memory allocated to myArray variable length array is deallocated after we return from vla method, but how come I can still correctly access the first and second element of the variable length array?
Is this behavior defined? or it is undefined behaviour that just happen to work?
myArray is a stack/auto variable created on the stack memory. Remember memory always exists. It is just owned by different pointers based on allocation and deallocation. The reason why you can still access same values is that the same piece of memory has not been assigned to another pointer and not been overwritten.
To evaluate it. Create another function that allocates same amount from stack but puts different values. Or add arguments in the same function and call it twice with different values. You will then see the difference.
#include <stdio.h>
int * vla(int n, int a, int b){
int myArray[n];
myArray[0] = a;
myArray[1] = b;
int * pointerToInt = myArray;
return pointerToInt;
}
int main(void){
int * pointerToInt = vla(10, 10, 11);
vla(10, 20, 21); // over write stack
printf("%d, %d", pointerToInt[0], pointerToInt[1]); // prints 20, 21
return 0;
}
By the way returning stack memory from vla is not a good idea. Dynamic memory is allocated from heap using malloc family of functions.
You can still correctly access the first and second element of the variable length array because you are assigning base address of the myArray to pointerToInt. Auto variables have a life inside the block only, but in this program we are using pointer to access the data in the memory, as long as that part of stack is not allocated to any other program, we can access that part of stack. If that part of stack is allocated to some other process we will get segmentation fault as we are trying to access unauthorized memory
I have a function that I pass an array into and an int into from my main function. I am doing operations to the array inside this new function, let's call it foo. In foo, I initialize another array with 52 cells all with 0. I do operations on the array that I passed from main, and transfer that data to the newly initialized array. I want to return the new array back to the main function. But of course, I can't return data structures like arrays. So I instead return an int pointer that points to this array. Inside the int main, I pass the pointer to have it point to various cells in the array. When I print the results of what the pointer is pointing to, it should either be pointing to 0 or an integer greater than 0. But instead, I get inconsistent results. For some reason, some of the values that SHOULD be 0, prints out garbage data. I've been trying to spot the bug for some time, but I just wanted a second hand look at it. Here is just the GENERAL idea for the code for this portion anyways...
int main(){
int *retPtr;
char input[] = "abaecedg";
retPtr = foo(input, size);
for(i=0; i<52; i++){
// error displayed here
printf("%d\n", *(retPr + i));
}
}
int foo(char input[], int size)
{
int arr[52] = {0}; // should initialize all 52 cells with 0.
int i=0, value; // looking for non-zero results in the end.
int *ptr = &arr[0];
for(i=0; i<size; i++){
if(arr[i] > 64 && arr[i] < 91){
value = input[i] - 65;
arr[value]++;
}
}
return ptr;
}
Hopefully this makes sense of what I'm trying to do. In the foo function, I am trying to find the frequency of certain alphabets. I know this might be a bit cryptic, but the code is quite long with comments and everything so I wanted to make it as succinct as possible. Is there any possible reason why I'm getting correct values for some (numbers > 0, 0) and garbage values in the other?
The reason you get garbage back is that the array created in foo is allocated in foos stack frame, and you then return a pointer into that frame. That frame is discarded when foo returns.
You should allocate the array on the heap (using malloc and friends) if you want it to remain after foo returns. Don't forget to free() it when you're done with the array.
int main(){
char input[] = "abaecedg";
int retPtr[] = foo(input, size); //An array and a pointer is the same thing
...
free(retPtr);
}
int *foo(char input[], int size)
{
int arr[] = calloc(52*sizeof(int); // should initialize all 52 cells with 0.
...
arr[value]++;
...
return arr;
}
Another way is to let foo take an array as a parameter and work with that, in this way:
int main(){
int ret[52] = {0};
...
foo(input, size, ret);
...
}
void foo(char input[], int size, int *arr)
{
...
arr[value]++;
...
return; //Don't return anything, you have changed the array in-place
}
The reason this works is because an array is the exact same thing as a pointer, so you are really passing the array by reference into foo. arr will be pointing to the same place as ret, into the stack frame of main.
In function foo the array arr is a local array, that is, allocated on the stack. You must not return any pointer of data allocated on the stack, since the stack is rewinded after you return from the function, and its content is no more guaratneed.
If you want to return an array you should allocate it on the heap using malloc, for example, and return the pointer malloc returned. But you will then have to free that memory somewhere in your program. If you fail to free it you will have what's called a "memory leak", which may or may not crash/disturb this program from running again, depending on your environment. A not clean situation, that's for sure.
That's why I consider C not so good for functional programing idioms, such as returning things from function (unless they are primitive types). I would achieve what you tried to do by passing another array to foo - an output array, companioned by a size variable, and fill that array.
Alternately, you could wrap the array within a struct and return that struct. Structs can be returned by value, in which case they are copied via the stack to the caller function's returned value.
Can't find what is wrong with this code, it works as expected when inputting exactly 4 values, but on the fifth call (before it even asks for scanf) it always gives me this error:
* glibc detected ./a2: double free or corruption (fasttop): 0x0916e018 **
Here's some code of my program:
typedef struct {
int i;
char str[25];
} typeX;
int main(){
int dSize = 0;
int *dSizePtr = &dSize;
dPointer = (typeX **)malloc(sizeof(typeX *)); // makes an array of pointers
int i;
for (i = 0; i < 100; i++)
makeElement(dPointer, dSizePtr); // Puts values into those pointers
free(dPointer);
return 0;
}
void makeElement(dPointer **, int *dSizePtr){
dPointer = (typeX **)realloc(dPointer, sizeof(typeX *)*(*dSizePtr+1)); // grow the array by one
if (typeX == NULL)
return; // some kind of quit statement, just return for now
dPointer[*dSizePtr] = (typeX *)malloc(sizeof(typeX)); // make a new pointer in the array
scanf("%s", dPointer[*dSizePtr]->str); // input the values of the struct (have to use scanf)
char input[20];
scanf("%s", input);
dPointer[*dSizePtr]->int = atoi(input);
++(*dSizePtr);
}
I know I don't have to make a dSizePtr and I can just pass in &dSize, but the way my program is currently set up (this isn't exactly the same, just compressed for readability), that's the way I have to pass it.
I honestly have no idea why this error is coming up. Been looking at my code for hours and reading online and haven't found a solution. Any help will be greatly appreciated!
The problem is that your function makeElement get the value of dPointer, not its reference. When you realloc the data, the originally allocated chunk is freed. But the dPointer outside of the makeElement scope is not changed;
The runtime error is delayed as the actual memory allocation is performed in quantities bigger than sizeof(typeX*)
This line is causing the double free.
dPointer = (typeX **)realloc(dPointer, sizeof(typeX *)*(*dSizePtr+1)); // grow the array by one
For the first few iterations of the loop in the caller the block of memory is large enough that realloc() doesn't have to do anything, and thus it returns the same pointer passed to it. But at some point the block of memory is too small and realloc() has to allocate a new block of memory and returns a pointer to it. That returned pointer is assigned to dPointer in makeElement() but it does not change the value of dPointer in the caller. So the caller continues to pass the old dPointer value into makeElement(), which passes it to realloc(), which notices that this pointer has been freed (by the call to realloc() that expanded the size of the array).
Update : Sorry, just a big mistake. It is meaningless to write int *a = 3; But please just think the analogy to the case like TCHAR *a = TEXT("text"); (I edited my question, so some answers and comments are strange, since they are for my original question which is not suitable)
In main function, suppose I have a pointer TCHAR *a = TEXT("text"); Then it excutes the following code:
int i;
for (i = 0; i < 1000; i++) {
a = test(i);
}
with the function TCHAR* test(int par) defined by:
TCHAR* test(int par)
{
TCHAR *b = TEXT("aaa");
return b;
}
My question is, after executing the above code, but before the program ends, in the memory:
1. the pointer `a` remains?
2. The 1000 pointers `b` are deleted each time the function test(...) exits ?
3. But there are still 1000 memory blocks there?
In fact, my question is motivated from the following code, which shows a tooltip when mouse is over a tab item in a tab control with the style TCS_TOOLTIPS:
case WM_NOTIFY
if (lpnmhdr->code == TTN_GETDISPINFO) {
LPNMTTDISPINFO lpnmtdi;
lpnmtdi = (LPNMTTDISPINFO)lParam;
int tabIndex = (int) wParam; // wParam is the index of the tab item.
lpnmtdi->lpszText = SetTabToolTipText(panel->gWin.At(tabIndex));
break;
}
I am thinking if the memory usage increases each time it calls
SetTabToolTipText(panel->gWin.At(tabIndex)), which manipulates with TCHAR and TCHAR* and return a value of type LPTSTR.
Yes, the pointer a remains till we return from the main function
The variable b (a 4-byte pointer) is automatic. It is created each time we call test function. Once we return from it, the variable disappears (the pointer). Please note, the value to which b points isn't affected.
No. In most of the cases, I think, there will be only one block allocated during compilation time (most likely in the read-only memory) and the function will be returning the same pointer on every invocation.
If SetTabToolTipText allocates a string inside using some memory management facilities new/malloc or some os-specific, you should do an additional cleanup. Otherwise there'll be a memory leak.
If nothing like this happens inside (it's not mentioned in the documentation or comments etc), it's most likely returning the pointer to some internal buffer which you typically use as readonly. In this case, there should be no concerns about a memory consumption increase.
You dont allocate any memory so you don't have to worry about memory being freed. When your vaiables go out of scope they will be freed automatically. In this function
int test(int par)
{
int *b = par;
}
you don't have a return value even though the function says that is will return an int, so you should probably do so as in this line
for (i = 0; i < 1000; i++) {
a = test(i);
}
you assign to a the value that is returned by test(). Also
int* a = 3;
int* b = par;
are asking for trouble. You are assigning integer values to a pointer variable. You should probably rethink your above code.
Pointer should contain adress... so int* a = 3 is something meaningless... And in function you don't allocate memory for int (only for par variable, which then destroy when the function ends), you allocate memory for storing adress in int* b, this memory also free when the funciton ends.