Difference between arrays and pointers in c? [duplicate] - c

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.

Related

C. malloc() and free() in function doesn't work [duplicate]

This question already has answers here:
How do I modify a pointer that has been passed into a function in C?
(7 answers)
What happens to memory after free()?
(4 answers)
Unable to check memory allocation size with sizeof() [duplicate]
(2 answers)
Closed 2 years ago.
Can someone tell me, why I can't allocate memory to the struct array through the init() function? When done manually in main, everything is fine. When trying it through init() nothing happens (Also no error message). The adress is always 0x0, I guess the null pointer.
#define GAMES 100
typedef struct{
double *scores;
}SCORES;
void init(SCORES *arr);
int main(){
SCORES *numbers = NULL;
init(numbers);
printf("Adress is: %p\n", numbers); //Still 0x0
return 0;
}
void init(SCORES *arr){
arr = (SCORES*) malloc(GAMES * sizeof(SCORES));
}
Trying it with the code below works for malloc. I get an adress but if I use free(), memory is still allocated.
void init(SCORES **arr){
*arr = (SCORES*) malloc(GAMES * sizeof(SCORES));
}
...
init(&numbers);
...
free(numbers);
In the first code snippet you're passing the value of the numbers variable. In the function you change a local variable, and doing so has no effect on the variable is the calling function.
In the second snippet you correctly pass the address of numbers so it can be set in the function, and the call to free is also correct. Just don't attempt to use the value of numbers after you free it, otherwise it's undefined behavior.

I am unable to run the following piece of code on my windows system, however it works on a linux system [duplicate]

This question already has answers here:
Segmentation fault on large array sizes
(7 answers)
Closed 3 years ago.
Program with large global array:
int ar[2000000];
int main()
{
}
Program with large local array:
int main()
{
int ar[2000000];
}
When I declare an array with large size in the main function, the program crashes with "SIGSEGV (Segmentation fault)".
However, when I declare it as global, everything works fine. Why is that?
Declaring the array globally causes the compiler to include the space for the array in the data section of the compiled binary. In this case you have increased the binary size by 8 MB (2000000 * 4 bytes per int). However, this does mean that the memory is available at all times and does not need to be allocated on the stack or heap.
EDIT: #Blue Moon rightly points out that an uninitialized array will most likely be allocated in the bss data segment and may, in fact, take up no additional disk space. An initialized array will be allocated statically.
When you declare an array that large in your program you have probably exceeded the stack size of the program (and ironically caused a stack overflow).
A better way to allocate a large array dynamically is to use a pointer and allocate the memory on the heap like this:
using namespace std;
int main() {
int *ar;
ar = malloc(2000000 * sizeof(int));
if (ar != null) {
// Do something
free(ar);
}
return 0;
}
A good tutorial on the Memory Layout of C Programs can be found here.

function returning pointer to string not working [duplicate]

This question already has an answer here:
Returning Local Variable Pointers - C [duplicate]
(1 answer)
Closed 7 years ago.
I want to know why doesn't the following work correctly? Though I have tried the other ways that work, but for the sake of more clarity I would like to know the problem occurring here.
char *fuc(char *s)
{
char t[10];
int r=0;
while(s[r] != '\0')
{
t[r] = s[r];
r++;
}
t[r]='\0';
return &t[0];
}
main()
{
char s[]="abcde";
char *p;
p=func(s);
puts(p);
}
In your fuc(), char t[10]; is a local variable. Once your function finishes execution, there is no existence of t. So, in the caller, the returned pointer becomes invalid.
Using that returned pointer further leads to undefined behaviour.
If you want to return the pointer from fuc(), you need to make use of dynamic memory allocation function , like malloc() and family. In that case, inside the caller function, once you're done using the memory, you need to take care for free()-ing the allocated memory, too.
That said, from the logical point of view, inside your fuc(), you're iterating over t without any check on the bounds. You should check for the size of t before using the index.
Furthermore, main() is not a proper form of the function. At Least, it should be int main(void).
Array t is local to function func() so once you exit the function you can't access array t which will lead to undefined behavior.
You should allocate memory on heap.
char *t = malloc(10);
Now you can return a pointer from the function func()

Getting run time error when accessing the freed pointer variable [duplicate]

This question already has answers here:
How much memory would be freed if pointer is changed in C?
(3 answers)
Closed 7 years ago.
i have one scenario like below
#include <stdio.h>
int main(void) {
int *p1=NULL;
int a;
p1=&a;
printf("%p\n",p1);
p1=NULL;
printf("%p\n",p1);
return 0;
}
In this case i have no problem at all.but if i use like this as below:
#include <stdio.h>
int main(void) {
int *p1=NULL;
int a;
p1=&a;
printf("%p\n",p1);
free(p1);
printf("%p\n",p1);
return 0;
}
In this case, i got run time error as below:
Runtime error time: 0 memory: 2052 signal:11
I want to know why it is happens like that. As far i know, freeing the
pointer will do same thing as assigning it NULL value(mean when we do
free(p) it also delete the pointer link to memory instead of deleting the
allocated memory space). I would rather if you could possibly suggest me
anything on that.
Thanks in Advance.
You are trying to free() memory you haven't allocated at all, which results in Undefined Behavior.
Therefore, you need a malloc() before the free() call like
p1 = malloc(sizeof(int));
free(p1); with a p1 value not returned by malloc() produces undefined behaviour.
You have undefined behaviour:
You can only free what you've malloced. p1 points to stack allocated memory so don't attempt to free it.
Be careful too when using *p1: it has the same rules as accessing a. You need to initialise a (either with a = ... or via the pointer with *p1 = ...) before doing anything else with it. Otherwise the program behaviour is undefined.

Can I check if a pointer was allocated by malloc/calloc/realloc? [duplicate]

This question already has answers here:
Check if a pointer points to allocated memory on the heap
(10 answers)
Can you determine if a string if freeable in C? [duplicate]
(5 answers)
Closed 9 years ago.
I was wondering is it possible to check if a pointer passed into a function was allocated by malloc/calloc/realloc?
int main(){
struct something o;
struct something *a;
a = malloc(sizeof(struct something));
freeSome(&o);/*This would normally throw an (corruption?) error*/
freeSome(a);/*This is fine*/
}
void freeSome(struct something * t){
if (/*expression here*/){
free(t);
}
}
I understand that usually you check to see if t == NULL, but I was just wondering if it was possible to see if memory has been allocated for the given pointer.
No, you can't.
Basically, you should not need to do this. If you are wanting to write a helper function to free some memory given a pointer, than you should awarely and explicitely pass a dynamically allocated pointer to a certain area of memory to do so.
Raw pointers in C cannot transport extra informations about the memory they are pointing to. If you want to have such informations, you will have to pass an additional wrapper that holds the pointer you are interested in, such as :
typedef struct my_pointer
{
void *ptr;
int is_dynamically_allocated;
} ptr;
But this would be a huge loss of memory/time.
No way to check, you ought to NULL initialize and then test whether NULL indeed
From section 7.20.3.2 The free function of C99 standard:
The free function causes the space pointed to by ptr to be deallocated, that is,
made available for further allocation. If ptr is
a null pointer, no action occurs. Otherwise, if the argument does not
match a pointer earlier returned by the calloc, malloc, or realloc
function, or if the space has been deallocated by a call to free or
realloc, the behavior is undefined.

Resources