Can array[]=malloc()ed?

D

dam_fool_2003

Friends,
cannot we malloc a array?
So, I tried the following code:

int main(void)
{
unsigned int y[3]={1,3,6},i,j;
for(i=0;i<3;i++)
printf("before =%d\n",y);
*y = 7; /* 1*/
for(j=0;j<3;j++)
printf("after =%d\n",y[j]);
return 0;
}

In the above I derefered *y in the line indicated by1 (correct me if I
have used a wrong term since pointers are derefered in this way. But
in the above I have used array but derefered as a pointer since
an array always decays into pointers.) the array's first element value
changes. Considering this as a kind of proof that *y pointes to the
first element in a array I wanted to malloc the array y. I tried
various syntax but I only get warnings.
*y = malloc(sizeof y);
In spite of the warnings I have compiled the code and the code I not
have any run time error. Can somebody tell me the correct syntax?
By the malloc of above the array's first element's mem get
allocated, Am I correct?

What happens I we use a multi dimensional array?
 
T

Thomas Matthews

Friends,
cannot we malloc a array?
So, I tried the following code:

int main(void)
{
unsigned int y[3]={1,3,6},i,j;
for(i=0;i<3;i++)
printf("before =%d\n",y);
*y = 7; /* 1*/
for(j=0;j<3;j++)
printf("after =%d\n",y[j]);
return 0;
}

In the above I derefered *y in the line indicated by1 (correct me if I
have used a wrong term since pointers are derefered in this way. But
in the above I have used array but derefered as a pointer since
an array always decays into pointers.) the array's first element value
changes. Considering this as a kind of proof that *y pointes to the
first element in a array I wanted to malloc the array y. I tried
various syntax but I only get warnings.
*y = malloc(sizeof y);


Since y is a pointer and *y is an integer, the compiler complained
that you were assigning a pointer from malloc() to an int.

Try this:
#define QUANTITY 4
int * x; /* one variable per line is preferred */
x = malloc(QUANTITY * sizeof(int));
/* or */
x = malloc(QUANTITY * sizeof(*x));

I'm not sure whether you are allowed to use y to point to something
else in your above code. I do know that it is not a safe practice
since the original array will be lost when you assign a new array
(dynamically allocated) to 'y'.

In spite of the warnings I have compiled the code and the code I not
have any run time error. Can somebody tell me the correct syntax?
By the malloc of above the array's first element's mem get
allocated, Am I correct?
No. The malloc function returns a pointer to dynamically allocated
memory; not the memory itself.
What happens I we use a multi dimensional array?
You need more space.
Read the C FAQ below which explains how to allocate memory for
a multi-dimensional array.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
 
E

Eric Sosman

Friends,
cannot we malloc a array?
So, I tried the following code:

int main(void)
{
unsigned int y[3]={1,3,6},i,j;
for(i=0;i<3;i++)
printf("before =%d\n",y);
*y = 7; /* 1*/
for(j=0;j<3;j++)
printf("after =%d\n",y[j]);
return 0;
}

In the above I derefered *y in the line indicated by1 (correct me if I
have used a wrong term since pointers are derefered in this way. But
in the above I have used array but derefered as a pointer since
an array always decays into pointers.) the array's first element value
changes. Considering this as a kind of proof that *y pointes to the
first element in a array I wanted to malloc the array y. I tried
various syntax but I only get warnings.
*y = malloc(sizeof y);


If `y' is still declared as shown above, `*y' is an `int'.
malloc() does not return an `int' value; malloc() returns a
pointer. You cannot store a pointer value in an `int' variable.
In spite of the warnings I have compiled the code and the code I not
have any run time error.

After giving you the diagnostic, the compiler apparently
tried to help you by altering your code to a correct form,
perhaps something like `*y = (int)malloc(sizeof y)'. If this
is what happened, the result was to forcibly convert the pointer
returned by malloc() into a corresponding `int' value, and store
that converted value in `*y'. The conversion might or might not
make sense; it might not even produce a legitimate `int' value;
your program might perfectly well explode at this point -- or it
might appear to do something sensible. The code as it stands is
incorrect, and there's really no telling what it might do.
Can somebody tell me the correct syntax?

No, because you haven't explained what you are trying to
do. The compiler (apparently) chose a correction in an attempt
to get some sense out of your code, but I am just as ignorant
as the compiler about your true intention, and my "correction"
is no more likely to be the right one than the compiler's was.
Neither of us can read your mind.
By the malloc of above the array's first element's mem get
allocated, Am I correct?

I'm sorry: I cannot understand this question at all.
What happens I we use a multi dimensional array?

Everything depends on how you use it.

Your understanding of arrays and of memory allocation seems
to be incomplete. I recommend that you study Sections 6 and 7
in the comp.lang.c Frequently Asked Questions (FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html

Sections 4 and 5 might also be helpful. Good luck!
 
N

Noah Roberts

Thomas said:
Friends,
cannot we malloc a array?
So, I tried the following code:

int main(void)
{
unsigned int y[3]={1,3,6},i,j;
for(i=0;i<3;i++)
printf("before =%d\n",y);
*y = 7; /* 1*/
for(j=0;j<3;j++)
printf("after =%d\n",y[j]);
return 0;
}
In the above I derefered *y in the line indicated by1 (correct me if I
have used a wrong term since pointers are derefered in this way. But
in the above I have used array but derefered as a pointer since
an array always decays into pointers.) the array's first element value
changes. Considering this as a kind of proof that *y pointes to the
first element in a array I wanted to malloc the array y. I tried
various syntax but I only get warnings.
*y = malloc(sizeof y);

I'm not sure whether you are allowed to use y to point to something
else in your above code.

No, he cannot. An array is not a valid lvalue, meaning it can never
appear on the left hand side of an assignment operator. If you want to
resize an array you must be using heap memory from the start.

What he can do is something akin to this:

unsigned int *y, i, j;
y = malloc(3 * sizeof(int));
y[0] = 1; y[1] = 3; y[2] = 6;
for (i = 0; i < 3; i++) print y;
y = realloc(y, 4 * sizeof(int));
y[3] = 7; // *y = 7 actually assignes y[0] = 7.
for (j = 0; j < 4; j++) print y[j];

Pointer syntax and array syntax are interchangeable as long as what you
are working with is a pointer. If it is an array you can still access
with *arr but you cannot manipulate arr in any way.

Things get complicated.

NR
 
E

Emmanuel Delahaye

In said:
cannot we malloc a array?

No. You can malloc a block of data and store its address into a pointer 'p'
of the same type, and act with 'p' like with an array, because '*(p + i)' is
the long form of 'p'.
 
M

Mark McIntyre

On 10 Oct 2003 09:09:01 -0700, in comp.lang.c ,
Friends,
cannot we malloc a array?

No. An array is a pre-allocated block of memory. You can't allocate it
with the *alloc functions.
unsigned int y[3];
*y = 7; /* 1*/

This sets the value of the first element to 1.
*y is the same as y[1]

In the above I derefered *y

Yes.
Considering this as a kind of proof that *y pointes to the
first element in a array

NO. Its a proof that *y IS the first element of the array !!
I wanted to malloc the array y.

You just can't do this. Forget the whole idea. An array is not
mallocable.
What happens I we use a multi dimensional array?

What happens when?
 
I

Irrwahn Grausewitz

Mark McIntyre said:
Friends,
cannot we malloc a array?

No. An array is a pre-allocated block of memory. You can't allocate it
with the *alloc functions.
unsigned int y[3];
*y = 7; /* 1*/
^

This sets the value of the first element to 1.
^
*y is the same as y[1]
^^ ^^^^

Err, is this Pascal programming by C-comment? ;-)

The above expression sets the value of the first element to 7;
*y is the same as y[0].

<SNIP>

Regards
 
B

Barry Schwarz

Friends,
cannot we malloc a array?
So, I tried the following code:

int main(void)
{
unsigned int y[3]={1,3,6},i,j;
for(i=0;i<3;i++)
printf("before =%d\n",y);
*y = 7; /* 1*/
for(j=0;j<3;j++)
printf("after =%d\n",y[j]);
return 0;
}

In the above I derefered *y in the line indicated by1 (correct me if I
have used a wrong term since pointers are derefered in this way. But
in the above I have used array but derefered as a pointer since
an array always decays into pointers.) the array's first element value
changes. Considering this as a kind of proof that *y pointes to the
first element in a array I wanted to malloc the array y. I tried


y is an array. In most contexts, the expression y is converted to a
pointer to the first element of the array. In this context, y is
treated as if you had written &y[0]. Therefore *y is treated as
*&y[0] which is the same as y[0].

Note that *y does not point to anything. (You would not say y[0]
points to the first element.) *y is the first element of the array,
the same as y[0].
various syntax but I only get warnings.
*y = malloc(sizeof y);

Assuming a prototype is in scope, the compiler knows malloc returns a
pointer to void. We already established that *y is an unsigned int.
You cannot assign a pointer to an int without a cast.
In spite of the warnings I have compiled the code and the code I not
have any run time error. Can somebody tell me the correct syntax?

The absence of a run time error simply means that your particular
instance of undefined behavior is unfriendly. The correct syntax is
*y = (int)malloc(...

Why you would want to do this is another question. Once you have the
address in an unsigned int, what are you going to do with it. You
cannot dereference it since you can only dereference pointers and we
have already established the *y is not a pointer.
By the malloc of above the array's first element's mem get
allocated, Am I correct?

If you rewrite this in English, we can probably tell you it is
incorrect.
What happens I we use a multi dimensional array?

If you don't change anything, you will have even worse undefined
behavior, if there are grades of badness.


<<Remove the del for email>>
 
M

Mantorok Redgormor

Eric Sosman said:
Friends,
cannot we malloc a array?
So, I tried the following code:

int main(void)
{
unsigned int y[3]={1,3,6},i,j;
for(i=0;i<3;i++)
printf("before =%d\n",y);
*y = 7; /* 1*/
for(j=0;j<3;j++)
printf("after =%d\n",y[j]);
return 0;
}

In the above I derefered *y in the line indicated by1 (correct me if I
have used a wrong term since pointers are derefered in this way. But
in the above I have used array but derefered as a pointer since
an array always decays into pointers.) the array's first element value
changes. Considering this as a kind of proof that *y pointes to the
first element in a array I wanted to malloc the array y. I tried
various syntax but I only get warnings.
*y = malloc(sizeof y);


If `y' is still declared as shown above, `*y' is an `int'.
malloc() does not return an `int' value; malloc() returns a
pointer. You cannot store a pointer value in an `int' variable.


You can't? What about the following:

int foo, *ptr;

ptr = &foo;
foo = (int)ptr;

After giving you the diagnostic, the compiler apparently
tried to help you by altering your code to a correct form,
perhaps something like `*y = (int)malloc(sizeof y)'. If this
is what happened, the result was to forcibly convert the pointer
returned by malloc() into a corresponding `int' value, and store
that converted value in `*y'. The conversion might or might not
make sense; it might not even produce a legitimate `int' value;
your program might perfectly well explode at this point -- or it
might appear to do something sensible. The code as it stands is
incorrect, and there's really no telling what it might do.


No, because you haven't explained what you are trying to
do. The compiler (apparently) chose a correction in an attempt
to get some sense out of your code, but I am just as ignorant
as the compiler about your true intention, and my "correction"
is no more likely to be the right one than the compiler's was.
Neither of us can read your mind.


I'm sorry: I cannot understand this question at all.


Everything depends on how you use it.

Your understanding of arrays and of memory allocation seems
to be incomplete. I recommend that you study Sections 6 and 7
in the comp.lang.c Frequently Asked Questions (FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html

Sections 4 and 5 might also be helpful. Good luck!


- nethlek
 
D

dam_fool_2003

My god,
Each element in the array is an int but not pointer to an int. If we
malloc the first element it will return a chunk of memory, which is a
pointer. Such a simple concept!
Some times my brain does not work correctly and gives UB!!

Can we allocate a array of pointer with malloc's by the following
method?
int main(void)
{
char *a = "dam",
*b="fool",
*c = "2003",
*d[3]={a,b,c};
unsigned int i;
for(i = 0;i<3 ;i++)
{
d = NULL;
d = malloc(sizeof **d);
if(**d == NULL)
{
printf("mem not allocated\n");
exit(EXIT_FAILURE);
}
else
printf("mem allocated\n");
}
return 0;
}

Thanks for all the replays
 
B

Barry Schwarz

My god,
Each element in the array is an int but not pointer to an int. If we
malloc the first element it will return a chunk of memory, which is a
pointer. Such a simple concept!
Some times my brain does not work correctly and gives UB!!

Can we allocate a array of pointer with malloc's by the following
method?

You can allocate an array of pointer but not by the method you wrote
int main(void)
{
char *a = "dam",

a is a pointer to char initialized to point to a string literal.
*b="fool",

b is also a pointer to char initialized to point to a different string
literal.
*c = "2003",

Ditto for c.
*d[3]={a,b,c};

d is an array of 3 pointer to char where each element of the array is
initialized to point to a different one of the three string literals
defined above. Of course this is a syntax error since the
initialization value must be a constant and not the value currently
contained in another variable. But then, you don't test most of your
code before you post it anyway. It turns out you don't use these
values so the initialization is irrelevant.
unsigned int i;
for(i = 0;i<3 ;i++)
{
d = NULL;


You also don't use this value but at least it is syntactically
correct, assuming you remembered to #include stdlib.h or one of the
other standard headers that defines NULL.
d = malloc(sizeof **d);


d is an array of pointer to char. *d is a pointer to char. **d is a
char. sizeof **d must be 1. Assuming you #include stdlib.h, d now
points to an area capable of holding exactly one char. On most
systems, this will be incapable of holding anything else. Did you
mean to include some multiplier as part of the argument to allow d
to point to the first element of an array?
if(**d == NULL)

A wonderful example of using gibberish to produce both syntax and
logic errors.

d is an array of pointers. *d is equivalent to *(d+0) which is
defined to be the same as d[0], the first pointer in the array. **d
is identical to *(*d) which, by substitution, is *(d[0]) which, by the
same logic, is the same as d[0][0]. Thus **d is the first character
pointed to by the first pointer in the array d.

At this point, since you haven't checked the return from malloc,
you don't know if this pointer points anywhere. The appearance of the
code suggests that you were attempting to test the return from malloc
but decided to get unnecessarily fancy. The return from malloc was
stored in d. If you want to test that return for success, test
d. Where did you come up with **d?

Even if you had used *d, which would have been syntactically,
correct, it would have produced the correct evaluation only for i=0.
The remaining iterations of the loop would have checked d[0] each time
instead of the d in which the result was stored.

On my system, NULL is defined as a pointer to void. **d is a char.
You cannot compare a pointer and a char. The compiler is required to
produce a diagnostic. Oops, sorry, you don't check your code before
posting.
{
printf("mem not allocated\n");

You need to #include stdio.h.
exit(EXIT_FAILURE);
}
else
printf("mem allocated\n");
}
return 0;
}

One of the secrets to successful programming is to think about the
problem for a while before writing any code. Your question asked
about allocating an array of pointers. I think most of us expected
your code to attempt to allocate an array of pointers. You didn't
allocate space for any pointers. You didn't allocate space for any
arrays. You didn't address your objective at all.

What your code could be credited with attempting is to allocate
multiple areas whose addresses will be kept in an automatic (not
allocated) array of pointers. That is not the same goal.

If you look in the faq (http://www.eskimo.com/~scs/C-faq/top.html),
you will find examples of how to allocate an array of pointers and
then allocate space for each of those pointers to point to. I
deliberately omit the section reference in the hope that, while you
are there, you will read the whole thing.


<<Remove the del for email>>
 
B

becte

I think you are confusing arrays and pointers. Arrays are not pointers!
You can use pointers to create dynamic arrays. Is that what you
want to do?
 
M

Mark McIntyre

You can't? What about the following:

int foo, *ptr;

ptr = &foo;
foo = (int)ptr;

AFAIR Implementation defined behaviour. A pointer may be, and probably
is on any sensible system , too large to fit into an int. The
pointer, after truncation, may not be a valid int value (trap
representations allowed?), and so on.

IOW Eric's remark was missing the words "usefully, portably or safely"
between "cannot" and "store".
 
E

Eric Sosman

Mark said:
AFAIR Implementation defined behaviour. A pointer may be, and probably
is on any sensible system , too large to fit into an int. The
pointer, after truncation, may not be a valid int value (trap
representations allowed?), and so on.

IOW Eric's remark was missing the words "usefully, portably or safely"
between "cannot" and "store".

"I meant what I said, and I said what I meant."
-- Theodore Geisel (aka Dr. Seuss)

You cannot store a pointer value in an `int' variable.
You can forcibly convert a pointer value to an `int' value
(subject to the problems mentioned by Mark and others) and
store *that* in an `int' variable, but you cannot store the
pointer value itself.
 
E

Eric Sosman

My god,
Each element in the array is an int but not pointer to an int. If we
malloc the first element it will return a chunk of memory, which is a
pointer. Such a simple concept!

... but it still seems to elude you -- or perhaps you
do in fact understand it, but your command of English is not
good enough to express what you know. A few facts:

- malloc() does *not* return "a chunk of memory."

- malloc() reserves a chunk of memory and returns a
pointer to its first byte (or fails to reserve a
chunk and returns NULL).

- "A chunk of memory" is *not* "a pointer."

- A suitably-sized and suitably-aligned chunk of
memory can be made to hold a pointer.

Once again, I recommend you study Sections 6 and 7
in the FAQ, and continue by reading Sections 4 and 5.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top