Memory Allocation In C , Use of Realloc - c

How do i use realloc function for calloc here. please guide ??
the first input of calloc function is giving me the right output but after using the realloc function my compiler just stuck , what mistake Am I doing here?
OUTPUT IS GIVEN:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int n,n2,sum=0,i;
int *ptr,*p;
printf("Enter Totoal Number of elements:");
scanf("%d",&n);
ptr=(int*)calloc(n,sizeof(int));
for(i=0;i<n;i++)
{
printf("Enter %d Element:",i+1);
scanf("%d",ptr+i);
sum=sum+*(ptr+i);
}
printf("The sum is: %d\n",sum);
printf("Enter new size:");
scanf("%d",&n2);
p=(int *)realloc(ptr,n2*sizeof(int));
for(i=0;i<n2;i++)
sum=sum+*(p+i);
printf("The new sum is:%d",sum);
free(ptr);
free(p);
}
OUTPUT HERE

Edit after update: you are double freeing the same pointer.
free(ptr);
free(p);
According to man realloc: realloc returns the pointer passed as argument, so ptr and p are the same. Actually you don't need two pointers here.
If you want to initialise go through ptr instead or p, which is what I guess you try to do then:
for(i=0;i<10*sizeof(int);i++)
You are looping 10 * sizeof(int) times to go through an array of size 10, accessing *(ptr+i) is like accessing ptr[i], ptr+i evaluates to the address ptr + sizeof(*p), you can read about pointer arithmetic if you want to learn more.
In your case, you are going out of bounds of your allocated memory, because your dynamically allocated array has size 10.

You simply do not reset sum to zero.
printf("Enter new size:");
scanf("%d",&n2);
p=(int *)realloc(ptr,n2*sizeof(int));
for(i=0;i<n2;i++)
sum=sum+*(p+i);
printf("The new sum is:%d",sum);
Before you ask for new size, you have already summed up the n entries.
Then you add on top of that the first n2 entries.
If you want to cound only the n2 entries, simply set sum=0; before you add up again.
Also You code will break if n2 > n as you do not provide new values for the new entries.
Another error:
free(ptr);
free(p);
You are not allowed to use ptr after you called realloc. It might have been free'd already in realloc if the memory location needed to be moved. Then that memory is not your's any more.
Or it might be same as p, then you will try to free the samem memory twice.
Both are no good ideas.

Related

Using realloc to double an arrays size during runtime. Is my code correct?

I am unsure if I am using the realloc function correctly.
In my program, I first ask the user for the size of the array and allocate memory for it using malloc, then initialise it with some values.
Then I want to make the same array twice it's size, using realloc. Here is my code. Am I using realloc to resize int *A correctly?
#include <stdio.h>
#include <stdlib.h>
int main(){
int n;
printf("Enter size of array\n");
scanf("%d", &n);
int *A = (int*)malloc(n*sizeof(int)); //dynamically allocated array
for (int i = 0; i < n; i++) //assign values to allocated memory
{
A[i] = i + 1;
}
A = (int*)realloc(A, 2*sizeof(int)); //make the array twice the size
free(A);
}
When using malloc() , don't cast the return value as said here
You are not using the right size. In hereint *A = (int*)malloc(n*sizeof(int)); the size given to malloc is n*sizeof(int). If you want twice that size, you should call realloc() with n*sizeof(int)*2 instead of 2*sizeof(int)
Handle realloc() failure. In case realloc(A, new_size) fails, A == NULL and you will have memory leak. So, use a different pointer B, check if (B != NULL) and then assign A = B (old_size = new_size). If B == NULL deal with the allocation fail
In this case it's easier to double the n before malloc so you don't have the use realloc, because you know, that you gonna double the arraysize. Using realloc can slow the working of the program, because if you make it longer, and the adresses after the currently allocated memories aren't free, then the whole array will be moved. Also you have the change the last line as it was suggested before me.

Array of Char pointers (strings) crashes after input?

I want to store an array of strings , count their length and re-arrange them with length-increasing-order (smallest->larger) using the algorithm mentioned below //
Swap holds a relatively big string to replace the order (when another min is found)
I could use realloc() but I am not considering defend programming yet
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i,j,N;
printf("\n Input amount of alphanumericals: ");
scanf("%d",&N);
{
int min;
char *swap=(char*)malloc(sizeof(char)*150);
char *A[N],**temp;
temp=A;
for(i=0;i<N;i++){
printf("\nInput %d element:",i+1);
fgets(temp+i,150,STDIN);
}
printf("\n\nData [");
for(i=0;i<N;i++)
printf(" %s",A[i]);
printf(" ]\n\n");
//Ins sort
for(i=0;i<N;i++){
min=i;//Assume current is min
for(j=i+1;j<N;j++){
//Compare assuming min with current
if(strcmp(A[j],A[min])<0){
min=j;
}
//If next is min replace in current position
if(min!=i){
swap=A[i];
A[i]=A[min];
A[min]=swap;
}
}
free(swap);
printf("\nAfter insertion point algorithm\n");
printf("\n\nInsertion Sorted Data [");
for(i=0;i<N;i++)
printf(" %s",A[i]);
printf(" ]");
}
return 0;
}
You are tying to free memory that has not been allocated using malloc:
char *A[N],**temp;
temp = A; // A is an automatic (AKA "stack") variable; now temp points to it as well
free(temp); // Undefined behavior
Inside the loop you are reading with gets into strings that have not been allocated:
gets(temp+i); // That's the same as gets(A[i]); Your A[i]s are unallocated.
As a side note, you should not use gets, because it is a prime source of buffer overruns. Use fgets instead, and pass stdin as the FILE* parameter. scanf with %20s is another alternative to limit the size.
In addition, since i goes from 1 to N, inclusive, this expression references one element past the A array on the last iteration:
gets(temp+i); // Undefined behavior when i==N
EDIT : Why is the code below crashes?
for(i=0;i<N;i++){
printf("\nInput %d element:",i+1);
fgets(temp+i,150,STDIN);
}
The code below crashes because you did not allocate memory for the individual strings:
for(i=0;i<N;i++){
printf("\nInput %d element:",i+1);
temp+i = malloc(151); // No need to multiply by sizeof(char) or cast to char*
fgets(temp+i,150,STDIN);
}
Note that you need to allocate one extra char for the null terminator.
You are not using gets correctly: take a look at its manual page [1]. Moreover, using gets is not recommended: better use fgets.
Also, gets is not allocating the string for you, so when you pass it a char * pointer, the pointer has to point to a valid memory location. Instead, your A[n] is an array of dangling pointers.
Then, why free(temp)? You must call free for each pointer allocated with malloc: not the case for temp.
Finally, please format your code: use indent.
[1] http://linux.die.net/man/3/gets

initializing an array using a function in C

I am doing an assignment for class and I thought I would bug you all with a question:
So the purpose of the program is for the user to enter the size of the array and then initialize it with some data. Max size is 20. My issue is that the array crashes when the sets the size beyond 14 and tries to initialize it. So forexample, if it sets the size as 20, it accepts it, but when I try to initialize it, it crashes. I have no idea what I am doing. your help is much appreciated.
Thank you very much,
Essi
int main ()
{
int sizeOfArray = 0; //size Of Array
float myArray[sizeOfArray];
//I have a piece a line or two of code that asks the user for the size of the
array
printf("Let's Initialize an array of size %d!!\n", sizeOfArray);
do
{
printf("Enter array element %d : ", initCounter+1);
myArray[initCounter] = userInitArray();
initCounter++;
}while (initCounter < sizeOfArray);
}
float userInitArray()
{
float num;
scanf("%f", &num);
return num;
}
These two lines
int sizeOfArray = 0; //size Of Array
float myArray[sizeOfArray];
Create an empty array. So whatever you try to store in this array later on is access out of bounds and invokes undefined behavior. The fact that your program crashes on 14th call is simply luck. It could have crashed on the first one just as well.
int sizeOfArray = 0; //size Of Array
float myArray[sizeOfArray];
Your array is created here with a size of zero. It doesn't magically expand when you later increase sizeOfArray. You need to get the size variable set first (from your 'line or two of code' user input) then create the array based on that.
You may also want to impose some sensible upper limit on your array size so you don't blow up your stack when trying, for example, to create a one-billion-entry array :-)
You have a (variable-length) array of size zero. You need to first ask for the size, and then allocate the array. Otherwise any attempts to assign to array elements would result in undefined behaviour.
You could do :
int sizeOfArray; //size Of Array
printf("tell me the size of the array");
scanf("%d",&sizeOfArray);
float myArray[sizeOfArray]; // not a good practice
The right way to do it would be:
int sizeOfArray; //size Of Array
float *myArray;
printf("tell me the size of the array");
scanf("%d",&sizeOfArray);
myArray=malloc(sizeof(float)*sizeOfArray);
You may use the pointer as a common array then.
and call like this: myArray[3] = doSomething();
EDIT Note that since you already know the max size you could avoid doing dynamic allocations listed above:
#Define MAXSIZE 20
int main ()
{
int sizeOfArray; //size Of Array
float myArray[MAXSIZE];
printf("tell me the size of the array\n");
scanf("%d",&sizeOfArray);
printf("\nLet's Initialize an array of size %d!!\n", sizeOfArray);
do
{
printf("Enter the element at myArray[%d] : ", initCounter+1);
myArray[initCounter] = userInitArray();
initCounter++;
}while (initCounter < sizeOfArray);
}
float userInitArray()
{
float num;
scanf("%f", &num);
return num;
}
Probably this last option is what your teacher is actually looking for.
You need to read sizeOfArray before you allocate myArray dynamically like this:
float * myArray = malloc(sizeOfArray * sizeof(float));
This is allocating sizeof(float) * sizeOfArray bytes of memory on heap and assigning address of allocated memory to myArray.
This is maybe hard to understand about arrays in C, they are really just pointers into memory - in your program the array myArray is allocated statically on stack and is of size 0. You cannot add any elements to it or assign to any index, it will not grow, its forewer 0 float elements long. Best thing that can happen to your program in this case is that it will crash. Worst case, it will not crash and strange things will happen;
You really should read something about memory allocation/management in C.
I think you forget to add function prototype in the beginning of your program (before main).
And also
int sizeOfArray = 0; //size Of Array
float myArray[sizeOfArray];
is wrong.
As you are using variable length array (valid in C99), you can do it as
int sizeOfArray; //size Of Array
printf("Let's Initialize an array of size %d!!\n", sizeOfArray);
float myArray[sizeOfArray];
dynamic arrays are not supported in C or C++.
Change your array to:
float* myAraray;
//later when you have the size , allocate it:
myArray = (float*)malloc(arrSize * sizeof(float));

Getting a user to input multiple values into a calloc array, C

trying to get my head around memory allocation and pointers in the C programming language.
If I allocate a space in memory for an array like so:
int *array = (int*) calloc(10, sizeof(int));
Can I then get the user to input multiple values to go into that array like this?
printf("Please enter values:\n");
scanf("%d", &*array);
Further more does the first line of code create a space in memory for an array and a pointer to that space. ie can I later point to a number in that array using *array? If this is not the case do I need some code along the lines of:
int *ptr;
int array;
ptr = array;
Quite new to programming so I apologize if my logic is not clearly shown. Also thanks in advance for any help.
Rus
You cannot do it without a loop. Here is what you can do:
for (int i = 0 ; i != 10 ; i++) {
printf("Please enter value for element %d:\n", i+1);
scanf("%d", &array[i]);
}
does the first line of code create a space in memory for an array and a pointer to that space?
Yes, it does. In C you do not need to cast the results of malloc/calloc/realloc, so you can re-write that line like this:
int *array = calloc(10, sizeof(int));

A small yet weird <Segmentation Fault>

I am not very experienced with C memory concepts. I tried searching for a solution, but could not find one.
I am just trying to create dynamic array in C. I tried to create it in this way while trying to check whether the addresses are contiguous. The program ran fine.
However, I got a segmentation fault after the statement system("pause"). I also tried to debug using the debugger, with no luck! I'm using Dev CPP.
Can anybody guide me?
#include<stdio.h>
#include<stdlib.h>
main()
{
int a[0], *ptr, i;
printf("%d", sizeof(a[0]));
a[0]=1;
for(i=1;i<10;i++)
{
ptr=(int *) malloc(sizeof(int));
printf("Enter a[%d]: ", i);
a[i]= *ptr;
scanf("%d", &a[i]);
}
i=0;
while(i<10)
{printf("\n%u", &a[i++]);}
free(ptr);
system("pause");
}
int a[0]
doesn't have any space allocated to it (its 0 width)
Yet you write to it on this line:
a[0]=1;
You also assume it has 10 elements here:
while(i<10)
{printf("\n%u", &a[i++]);}
free(ptr);
Practically speaking, as this is just stack memory, you're just writing to another piece of the stack. You could, for example, be overwriting the value of ptr. Often this can go undetected until the stack is unwound and part of it is apparently corruptted. Here the stack is unwound right after system("pause"), when main returns.
(Also, if ptr is overwritten by your writes to a you can't be sure that free does anything reasonable.)
To allocate a 10 integer array, use the syntax:
int a[10];
Then you can use a[0] up to a[9]. But this is C don't expect anything to protect you when you try to read/write to a[10].
There are lots of problems in your code.
int a[0]. You are defining an array of 0 elements. In C this will not work. You cannot do a[0]=1 since it will work only if a is an array of 1 or more elements.
It gets worse with a[i]=*ptr. 2 problems here, as pointed above a[1], a[2], etc don't exist. and the second problem is you allocated ptr but assigning *ptr which might be having some garbage.
It is just the beginning.
int a[0], ...;
...
a[0]=1;
You are writing out of bounds. This is undefined behavior.
First your a[0] should be a[10] for the way your are trying to use it. Second, just malloc to the pointer and it is basically an array. Though you don't need to do it in a for loop. You can just say ptr = malloc(10 * sizeof(int)); and you will be good. No need to cast it. You can access it's elements through the array subscript like ptr[9].
Well, your dealing with a is epical:
int a[0]; // no-items array
...
a[0]=1; // WHAT?
for(i=1;i<10;i++)
{
ptr=(int *) malloc(sizeof(int));
a[i]= *ptr; // a was int or pointer? And A[9]?
}
Several problems: 1) Your expecting your array to be 10 elements long but you're declaring it with 0, and make it an array of pointers;
int *a[10];
then
a[i] = (int*)malloc(sizeof(int));
and when freeing;
free(a[i]);

Resources