Reputation: 135
I'm a novice user of C language. I have a problem in allocating a dynamic array.
I used to allocate memory outside the loop such as a=(int*)malloc(5* sizeof(int));
and every thing worked fine. Now I want to allocate memory to each element one by one in a loop using malloc()
, but the code is not working.
I've tried different options like scanf("%d",a) &a++,scanf("%d",&a[i]);
etc but could not succeed. If anyone can tell me what I was doing wrong and explain to me the concept thoroughly, I'll be thankful.
The code which I'm having problems with is the following:
#include <stdio.h>
#include<stdlib.h>
int main()
{
int *a;
int i;
system("clear");
for(i=0;i<5; i++)
{
a=(int *)malloc(sizeof(int));
printf("%u",&a);
printf("please enter the element in array");
scanf("%d",a[i]);
}
for(i=0;i<5; i++)
{
printf("\nthe %d entry in the array %d",i,a[i]);
}
return 0;
}
Upvotes: 1
Views: 296
Reputation:
I believe I have found the solution to your predicament. Simply follow these steps:
(1) Shift the statement:
a=(int *)malloc(sizeof(int));
out of the for loop (put it just before the for), & change it to:
a=(int *)malloc(5 * sizeof(int));
(2) Change your scanf statement to:
scanf("%d",&a[i]);
That should do the trick.
Upvotes: 0
Reputation: 753595
As everyone has pointed out, you really don't want to allocate each element of the array separately. However, if, despite the advice, you decide you do, then you need both an array of pointers and the individual pointers:
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
enum { ARRSIZE = 5 };
static void err_exit(const char *msg)
{
fprintf(stderr, "%s\n", msg);
exit(1);
}
int main()
{
int **a;
int i;
a = (int **)malloc(sizeof(*a)*ARRSIZE);
if (a == 0)
err_exit("out of memory");
for (i = 0; i < ARRSIZE; i++)
{
a[i] = (int *)malloc(sizeof(int));
if (a[i] == 0)
err_exit("out of memory");
printf("%" PRIuPTR "\n", (uintptr_t)a[i]); // Print allocated address
printf("please enter the element in array: ");
if (scanf("%d", a[i]) != 1)
err_exit("failed to read a valid integer");
}
for (i = 0; i < ARRSIZE; i++)
{
printf("the %d entry in the array %d\n", i, *a[i]);
}
return 0;
}
Additional points:
malloc()
worked.scanf()
can lead to a world of pain. You should check its return status too. If you type a letter instead of a digit, your code will fail rather horribly. Generally, you are better off using fgets()
and sscanf()
.err_exit()
; that is just a trivial version of what could be a much more complex system of functions, but having such functions available means you are less likely to skimp on error reporting.uintptr_t
to print addresses as integers, and the <inttypes.h>
header, and the names defined in there such as PRIuPTR
. (I usually print addresses in hex, but decimal isn't automatically wrong.) The <inttypes.h>
header is from C99; that might cause you problems if your C compiler is retrograde enough not to provide C99 support.int
type; on a 64-bit machine, it uses vastly more memory than the original solution.malloc()
. I prefer it, in part because I learned C on a machine where the cast was crucial, and in part because the cast is mandatory in C++, and I like my code to work in the C subset of C++ even when I'm writing in C. (The compiler in question was before there was a standard C; it was word-addressed machine; malloc()
returned char *
, but the bit pattern for a char *
was different from the bit pattern for an anything *
(e.g. int *
) to the same address.)Upvotes: 1
Reputation:
a[i]
is equivalent to *(a+i)
scanf
needs the address of a which can be supplied here by using &(a[i])
or simply (a+i)
.
Instead, you are passing it a[i]
, which refers to data stored at the location (a+i)
.
Upvotes: 1
Reputation: 26086
unwind's answer is the explanation, but here's some code to demonstrate
#include <stdio.h>
#include <stdlib.h>
int main(){
int *a;
int size = 5;
int i = 0;
a = malloc(sizeof(int)*size);
for(i=0;i<size;i++){
printf("%u: ",&a);
printf(" please enter the element in the array> ");
scanf("%d", &a[i]);
}
for(i=0;i<size;i++){
printf("index %d in the array is %d\n",i,a[i]);
}
free(a);
return 0;
}
Upvotes: 0
Reputation: 6233
The whole thing is, to be honest, a disaster. If you are learning and are completely confused, try reading up on C pointers.
Look, perhaps try something like this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *a;
int i;
system("clear");
a=(int *)malloc(sizeof(int)*5);
for(i=0;i<5; i++)
{
printf("please enter the element in array");
scanf("%d",a+i);
}
for(i=0;i<5; i++)
{
printf("\nthe %d entry in the array %d",i,a[i]);
}
return ;
}
Or the way I would do it:
#include <vector.h>
#include <stdio.h>
int main()
{
vector<int> a;
int i;
system("clear");
for(i=0;i<5;i++)
{
printf("please enter the element in array");
int n;
scanf("%d",&n);
a.push_back(n);
}
for(i=0;i<5; i++)
{
printf("\nthe %d entry in the array %d",i,a[i]);
}
return ;
}
You see, you cannot simply allocate new memory and expect to be "added" to previously allocated memory. The only way to add to or resize a block of memory is to recreate it, and carry over the data.
Upvotes: -1
Reputation: 399763
An array is a single "object" (a single thing) that has space for many items, all of the same type.
Your expectation to be able to somehow allocate one item at a time is incorrect, that's simply not how arrays work.
You should do like you first said, a single malloc()
allocating room for 5 items, and then just store each one to its proper position in the array inside the loop.
I would recommend using scanf("%d", &a[i])
to read and store into the array. There are other ways of writing the second argument, but this (in my opinion) is the clearest and best for a beginner. It reads as "the address of the i:th item in the array a".
Upvotes: 5
Reputation: 304
The problem is that you create a new array with size = 1 everytime in the for loop.
So everytime "a" has place for one integer.
Upvotes: 0
Reputation: 13690
In each iteration your code overwrites the old value of a. So you lose the address of the previously mallocated memory.
Each malloc allocates only sapce for one int. It's illegal to dereference the pointer with an index > 0. That's why your code gives undefined behaviour.
Upvotes: 1