In this program new value will be added to the array at end. When the memory is reallocated why it is not reflected back to the actual parameter
#include<stdio.h>
void insertion(int* arr,int *n)
{
int val,n1=*n;
int *temp;
printf("\nEnter element to append");
scanf("%d",&val);
temp=malloc(sizeof(int)*n1);
for(i=0;i<n1;i++)
{
temp[i]=arr[i];
}
n2=n1+1;
arr=malloc(sizeof(int)*n2);
for(i=0;i<n1;i++)
{
arr[i]=temp[i];
}
arr[n1]=val;
*n=n2;
}
int main()
{
int n=4;
int arr[4]={1,2,3,4},i;
insertion(arr,&n);
for(i=0;i<n;i++)
{
printf("\t%d",arr[i]);
}
}
There are two reasons for this.
First, you're assigning the return value of malloc to arr, which is a parameter to the function and therefore local. This means that changing the value of arr isn't reflected in the calling function.
Even if you fixed this, you would have a problem because arr in main is an actual array allocated locally, so you can't change its size.
You would first need to change arr in main to be a pointer and to allocate space for it with malloc so that you can use realloc later, and you need to change insertion to take a int ** so that the actual pointer value in main can be changed.
Because the parameter is passed by value.
You change arr in insertion, there's no reason that should change arr in main. They're different variables. This is how C works.
But in main arr is an array, which means it couldn't be changed even if you got the code right.
Here's how to do it right, if you want to change something in main you have to return the vaue from your function.
#include<stdio.h>
int* insertion(int* arr,int *n)
{
...
return arr; // return the new value of arr
}
int main()
{
int n=4;
int* arr = malloc(n*sizeof(int)); // arr is a pointer, not an array
for (int i = 0; i < n; ++i)
arr[i] = i+1;
arr=insertion(arr,&n); // get the returned value from insertion
for(i=0;i<n;i++)
{
printf("\t%d",arr[i]);
}
}
Related
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 1 year ago.
#include<stdio.h>
#include <stdlib.h>
void deal_queries(int *arr, int limit, int numQueries, int filled) {
// Write your code here
for(int i=0;i<filled;i++)
{
printf("%d ",*(arr+0));
}
}
int * read_input(int N,int n){
//declare dynamic array of size N
// take input n integers and store them in the array and return pointer to this
int i;
int *ptr;
int array[N];
ptr=array;
for(i=0;i<n;i++)
{scanf("%d ",ptr);ptr++;}
ptr=array;
return (ptr);
}
int main()
{
int N,Q,n;
scanf("%d %d %d",&N,&Q,&n);
int* arr=read_input(N,n);
printf("%d ",*(arr+0));
deal_queries(arr,N,Q,n);
return 0;
}
when I print arr elements in main function I get correct values but if I pass them into deal with queries function I get random values can anyone explain why is this happening?
The variable array is local to read_input, so its life ends when returing from the function and accessing it after that is illegal.
Instead of that, you should allocate an array on the heap and use that.
#include<stdio.h>
#include <stdlib.h>
void deal_queries(int *arr, int limit, int numQueries, int filled) {
// Write your code here
for(int i=0;i<filled;i++)
{
printf("%d ",*(arr+0));
}
}
int * read_input(int N,int n){
//declare dynamic array of size N
// take input n integers and store them in the array and return pointer to this
int i;
int *ptr;
int *array=malloc(sizeof(*array)*N); /* allocate an array on the heap */
if(array==NULL) return NULL; /* check if allocation succeeded */
ptr=array;
for(i=0;i<n;i++)
{scanf("%d ",ptr);ptr++;}
ptr=array;
return (ptr);
}
int main()
{
int N,Q,n;
scanf("%d %d %d",&N,&Q,&n);
int* arr=read_input(N,n);
if(arr==NULL) return 1; /* check if allocation succeeded */
printf("%d ",*(arr+0));
deal_queries(arr,N,Q,n);
free(arr); /* free allocated array */
return 0;
}
You return the pointer to the local automatic storage variable which is UB as the variable stops existing when the function returns.
int array[N];
ptr=array;
for(i=0;i<n;i++)
{scanf("%d ",ptr);ptr++;}
ptr=array;
return (ptr);
You need to make it static (bad way) or dynamically allocate the memory
static int array[N];
ptr=array;
or better
//int array[N];
ptr=malloc(sizeof(*ptr)*N);
The error is in read_input where you have:
int array[N];
ptr=array;
return (ptr);
The variable array is a local variable in the function. And the assignment to ptr makes it point to the first element of this local array. This pointer will become invalid as soon as the function returns and the life-time of array ends.
You need to allocated the array dynamically using malloc instead:
int *array = malloc(N * sizeof *array);
int *ptr = array;
// Fill array using the ptr variable...
return array;
The pointer isn't a problem, it's what it points to. Here is the issue:
int * read_input(int N,int n) {
...
int array[N]; // This array is in automatic memory,
ptr=array; // so it is valid only inside read_input
...
return (ptr); // you are returning a pointer to it
}
In order to do what you want to do you need to use malloc:
int* ptr = malloc(sizeof(int)*N);
Use another pointer in the loop, or apply indexing to ptr, like this:
for (i = 0 ; i < n ; i++) {
scanf("%d ", &ptr[i]);
}
As you can see in the code below I tried to print an array that I created in a different function. The output was totally different numbers compares to what I expected: numbers between 0 - 20 were set but I got some negative values.
So my question is why is this happening? And how to fix it if it even possible?
#include <stdio.h>
#include <time.h>
#define LEN 10
int* creatingArray();
void printingArray(int* array);
int main(void)
{
int* pointer_array = creatingArray();
printingArray(pointer_array);
getchar();
return 0;
}
int* creatingArray()
{
srand(time(NULL));
int array[LEN] = { 0 };
int* i = 0;
for (i = array; i < array + LEN; i++)
{
*i = rand() % 20;
}
return array;
}
void printingArray(int* array)
{
int* i = 0;
for (i = array; i < array + LEN; i++)
{
printf("\n%d\n", *i);
}
}
Pay attention to this code:
int* creatingArray()
{
// stuff
int array[LEN] = { 0 };
// more stuff
return array;
}
array is a local variable, so it gets destroyed when the function returns. You then have a pointer to a destroyed variable. The space where it was will (most likely) continue to hold the data you put there - until the memory gets reused for something else and overwritten.
and how to fix it if it eve/n possible?
Several options:
Make array a static variable. Then it will not be destroyed when the function returns. (This also means that every time you call creatingArray it will use the same array, instead of a new one)
Make array global.
Move array to main, and pass a pointer to it into creatingArray, instead of having creatingArray return one. Then, since it's a local variable in main, it will only be destroyed when main returns.
Use malloc to allocate some space that will not be cleaned up automatically when the function returns.
Hello I'm build a function are printing array with pointers
on c with Visual Studio 2015.
while i run the function this send me this massage:
Run-Time Check Failure #2 - Stack around the variable 'arr' was corrupted.
this the function:
void arrprint(int* arr, int size)//printing numbers:
{
size = (int)arr + size*sizeof(int);// the last adress of the array
int* firstAdress = arr;
for (arr=firstAdress; arr < size; arr++)
{
printf("%2d", *arr); //printing
}
*arr = firstAdress; //for not destroy the array
printf("\n");
}
thanks for helpers
This line
*arr = firstAdress; //for not destroy the array
destroys the array. You are writing into the memory when you dereference arr.
Since in C, everything is passed by value, you do not have to worry about corruption when you change arr in the function. So, you do not need firstAdress.
void arrprint(int* arr, int size)//printing numbers:
{
int* lastAddress = arr + size;
int* firstAdress = arr;
for (arr=firstAdress; arr < size; arr++)
{
printf("%2d", *arr); //printing
}
printf("\n");
}
After Updating, the code should look like this. You should notice that arr which is being changed here, is only being changed in this function, and the actual array pointer (in the caller function) is intact and safe.
You're trying to use size as an int *. Use an actual int * instead.
Also, by setting *arr = firstAddress, what you're really doing is writing the address of the array into the first element in the array. Also, since arr is a local variable, changes to it don't affect the variable in the calling function.
void arrprint(int* arr, int size)//printing numbers:
{
int *lastAddress = arr + size;
int *firstAdress = arr;
for (arr=firstAdress; arr < lastAddress; arr++)
{
printf("%2d", *arr); //printing
}
printf("\n");
}
Personally think the best solution is:
void arrprint(int* arr, int size)//printing numbers:
{
int *lastAddress = arr + size
int *firstAddress = arr;
for (firstAddress = arr; firstaddress < lastAddress; firstaddress++)
{
printf("%2d", *firstAddress); //printing
}
printf("\n");
}
Reason you do not alter the original pointer. You can also use const int* arr in the function declaration, then you will get a compiler error if you dereference the pointer.
#include<stdio.h>
#include<conio.h>
float smallest(int arr[],int k,int n);
void sort(int arr[],int n);
void main()
{
int arr[20],i,n,j,k;
clrscr();
printf("\nEnter the number of elements in the array: ");
scanf("%d",&n);
printf("\nEnter the elements of the array");
for(i=0 ; i < n ; i++)
{
printf("\n arr[%d] = ",i);
scanf("%d",&arr[i]);
}
sort(arr,n);
printf("\nThe sorted array is: \n");
for(i=0 ; i < n ; i++)
printf("%d\t",arr[i]);
getch();
}
int smallest(int arr[],int k,int n)//smallest function
{
int pos=k,small=arr[k],i;
for(i=k+1;i<n;i++)
{
if(arr[i]<small)
{
small=arr[i];
pos=i;
}
}
return pos;
}
void sort(int arr[],int n)//sorting function
{
int k,pos,temp;
for(k=0 ; k < n ; k++)
{
pos=smallest(arr,k,n);
temp=arr[k];
arr[k]=arr[pos];
arr[pos]=temp;
}
}
In the above program the sort function is being called from main but the return type of sort is void and it still returns the sorted array. As after sorting the array the function should return the sorted array back to the calling function to print the sorted array but the program runs perfectly. How is that happening?
When you declare
int arr[20];
you can say "arr is an array of 20 integers". But arr is a pointer to an integer as well, pointing to the first integer in a row of 20. So de-referencing *arr is an integer, the same as arr[0] in fact.
This means when you pass arr to a function you only pass a pointer to that function. The function in this case works on the (copied) pointer. But this very pointer points exactly to the same memory as your original arr declared in main(). And that's the reason why manipulating arr in sort() is in fact manipulating arr in main().
When passing an array as a parameter, this
int smallest(int arr[],int k,int n)
means exactly the same as
int smallest(int *arr,int k,int n)
For example
#include<iostream>
void printArray(int data[])
{
for(int i = 0, length = sizeof(data); i < length; ++i)
{
std::cout << data[i] << ' ';
}
std::cout << std::endl;
}
int main()
{
int data[] = { 5, 7, 8, 9, 1, 2 };
printArray(data);
return 0;
}
You will see that only the first 4 elements of the array are printed. The sizeof(data) returns a value of 4! That happens to be the size of the pointer used to pass the array to printArray().
First the array does not get copied. The pointer to the first element of the array is copied
First, there is no connection between any function argument what is, or is not passed using a return statement with an expression according to the function's return type.
While it is true that all parameter passing in C is by value - copy the value to a "local parameter variable" - nothing is assumed about what is to happen at the memory location a pointer is referencing. So, a function can make any changes in the calling environment, even without returning a value.
As to parameters declared as being aType name[]. this is merely syntactic sugar for const aType* name.
I have the following function in C:
int[] function(int a){
int * var = (int*)malloc(sizeof(int)*tags);
....
}
*var is it a pointer to an array var?
If yes, how can I return the array (var) in the function?
You can't really return an array from a function, but a pointer:
int * function(int a){
int * var = malloc(sizeof(int)*tags);
//....
return var;
}
This code below could clarify a bit how array and pointers works.
The function will allocate memory for "tags" int variables, then it will initialize each element with a number and return the memory segment that points to the array.
From the main function we will cycle and print the array element, then we will free the no longer needed memory.
#include <stdio.h>
#include <stdlib.h>
int *function(unsigned int tags) {
int i;
int *var = malloc(sizeof(int)*tags);
for (i=0; i < tags; i++) {
var[i] = i;
}
return var;
}
int main() {
int *x;
int i;
x = function(10);
for (i=0; i < 10; i++) {
printf("TEST: %i\n", x[i]);
}
free(x); x=NULL;
return 0;
}
How about:
int* function(int tags){
int * var = malloc(sizeof(int)*tags);
//....
return var;
}
Arrays and pointers to the base element type are (mostly) synonymous in C/C++, so you can return a pointer to the first element of an array and use that as if it was the array itself.
Note, your code has an input parameter a, but using tags to allocate the memory for the array. I assumed in the above code that you wanted to use the input parameter for that purpose
Also, you will have to call free() on the pointer returned by function above, when you are no longer using the array, to avoid memory leaks. malloc above allocates memory enough to hold tags number of ints, so the array is equivalent to int var[tags];
UPDATE: removed cast for malloc's return
In C, functions cannot return array types. For your purposes, you want to return a pointer to int:
int *function(int a)
{
int *var = malloc(sizeof *var * tags); // where is tags defined?
// are you sure you don't mean a here?
...
return var;
}
This will allocate a block of memory large enough to hold tags integer values and assign the address of the first element of that block to var. Note that var is a pointer to int, not a pointer to an array of int. That pointer is what gets returned from the function.
You can use the subscript oprerator on a pointer expression as though it were an array, like so:
int a = ...;
int *arr = function(a);
...
arr[0] = 0;
arr[1] = 1;
...
arr is a pointer expression, not an array expression, so sizeof arr will return the size of the pointer type, not the size of the block of memory that it points to (because of this, you will want to keep track of the number of elements you allocated separately).
In C an array is basically the same type as a pointer to an element of the array.
So char[] is basically char*
Don't forget to keep track of the size of the array, also I noticed that tags seems to be a global variable, most of the time it's a good idea to avoid global variables
Here is some example code:
#include <stdio.h>
#include <stdlib.h>
int* foo(size_t arrSize){
int* arr = (int*) malloc(sizeof(int)*arrSize);
return arr;
}
int main (int argc, char** argv){
printf("Printing array:\n");
int* arr = foo(42);
for(int i=0; i <42; i++){
arr[i]=i;
}
for (int i=0; i < 42; i++){
printf("Element: %d: %d\n", i, arr[i]);
}
free(arr);
return 0;
}