malloc

H

Hrv'uljak

Anybody has a better solution? How to avoid memory allocation in main
function?

Thanks!

--------
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <malloc.h>

int a(char *n) {
n=(char *)realloc(n, 10);
strcpy(n, "abcdefg");
return 0;
}

int main()
{
char *nn=0;
nn=(char *)malloc(1);

a(nn);

printf("%c", nn[5]);

getch();
return 0;
}
 
M

Marc Boyer

Le 18-10-2005 said:
Anybody has a better solution? How to avoid memory allocation in main
function?

Since your solution is false, it not too hard to get a
better one ;-)
--------
#include <stdio.h>
#include <conio.h> useless
#include <string.h>
#include <malloc.h>

int a(char *n) {
n=(char *)realloc(n, 10);

If the return value of realloc is != from n,
then, this value is only known in function a,
not in the main.
I assume you have tested it, and it have run
successfully at least once.

But make the test with realloc(n, 100000);
strcpy(n, "abcdefg");
return 0;
}

int main()
{
char *nn=0;
nn=(char *)malloc(1);

a(nn);

printf("%c", nn[5]);

getch();
return 0;
}

What about this ?

char* a(){
char* res= malloc( sizeof("abcdef") );
if (res)
strcpy(res, "abcdef");
return res;
}

int main(){
char *nn= a();
if (nn)
printf("%c", nn[5]);
return nn!=NULL;
}

Marc Boyer
 
V

Vimal Aravindashan

Marc said:
Not really. The OP does a call getch(), so he needs it. But it is a
platform dependent header, and is not a part of standard C.
malloc.h is now obsolete. Replace it with stdlib.h
int a(char *n) {
n=(char *)realloc(n, 10);


If the return value of realloc is != from n,
then, this value is only known in function a,
not in the main.
I assume you have tested it, and it have run
successfully at least once.

But make the test with realloc(n, 100000);

strcpy(n, "abcdefg");
return 0;
}

int main()
{
char *nn=0;
nn=(char *)malloc(1);

a(nn);

printf("%c", nn[5]);

getch();
return 0;
}


What about this ?

char* a(){
Although it is the same as:
char* a(void) {
...
}
there are differences (Marc's doesn't have a prototype, mine does), so use
char* a(void) {
...
}
char* res= malloc( sizeof("abcdef") );
Although the above does what you expect it to, I'd prefer
char *res = malloc( strlen("abcdef") * sizeof(char) );
OR
char *res = malloc( strlen("abcdef") * sizeof(*res) );
if (res)
strcpy(res, "abcdef");
return res;
}

int main(){
This has to be int main(void)
char *nn= a();
if (nn)
printf("%c", nn[5]);
return nn!=NULL;
}

Marc Boyer

Cheers,
Vimal.
 
C

Christopher Benson-Manica

Hrv'uljak said:
#include <stdio.h>
#include <conio.h>

Nonstandard. Get acquainted with this group.

http://www.ungerhu.com/jxh/clc.welcome.txt
http://www.eskimo.com/~scs/C-faq/top.html
http://benpfaff.org/writings/clc/off-topic.html
#include <string.h>
#include <malloc.h>

Nonstandard. The header you want is said:
int a(char *n) {
n=(char *)realloc(n, 10);

*click* Do not cast the return value of *alloc(). Please read the group
archives for more information and leave a message at the tone. *beep*
strcpy(n, "abcdefg");
return 0;
}
int main()
{
char *nn=0;
nn=(char *)malloc(1);

Another unnecessary cast. Furthermore, you may delete this line with
no effect on your program; passing NULL as the first argument to
realloc() is exactly identical to calling malloc() and is perfectly
legal.

A previous poster already explained why this doesn't work...
printf("%c", nn[5]);

....and why this is broken as a result.
 
D

David Resnick

Vimal said:
Although the above does what you expect it to, I'd prefer
char *res = malloc( strlen("abcdef") * sizeof(char) );
OR
char *res = malloc( strlen("abcdef") * sizeof(*res) );

Two issues. Really bad, needs to be strlen("abcdef") + 1,
or you don't have room to terminate the string. sizeof
includes that... Slightly bad, sizeof(char) is by definition
always exactly 1, so its inclusion is sort of obfuscatory.
sizeof (*res) is only slightly better. If you, say, switch to
wide chars other changes are also needed (can't use strlen, etc).


-David
 
R

Richard Tobin

Anybody has a better solution? How to avoid memory allocation in main
function?
int a(char *n) {
n=(char *)realloc(n, 10);
strcpy(n, "abcdefg");
return 0;
}

int main()
{
char *nn=0;
nn=(char *)malloc(1);

a(nn);

You can just omit the malloc(), so that the argument is null when
realloc() is called. realloc() behaves just like malloc() if its
argument is null.

But your program has several other problems; in particular after the
realloc() the variable nn in main doesn't point to anything useful.
(If it works for you now, it's just because the realloc() happens not
to do anything: quite likely malloc(1) in fact allocates more than 10
bytes.)

Here are some alternatives:

- have a() return the realloc()ed string
- have a() malloc the string and return it
- pass a() a pointer to the pointer, so that it can update it after
the realloc:

...
a(&nn);
...

int a(char **n)
{
char *t = realloc(*n, 10);
if(!t)
error...
strcpy(t, ...)
*n = t;
return 0;
}

-- Richard
 
M

Martin Ambuhl

Hrv'uljak said:
Anybody has a better solution? How to avoid memory allocation in main
function?

Thanks!
There is no standard header said:
#include <string.h>
#include <malloc.h>
There is no standard header said:
int a(char *n) {
n=(char *)realloc(n, 10);
strcpy(n, "abcdefg");
return 0;
}

int main()
{
char *nn=0;
nn=(char *)malloc(1);
a(nn);
printf("%c", nn[5]);
getch();
return 0;
}

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define SILLYSTRING "abcedef"

void a(char **n)
{
char *t;
t = realloc(*n, strlen(SILLYSTRING) + 1);
*n = t; /* even if realloc fails, in this case.
Not a good idea as a rule */
strcpy(*n, SILLYSTRING);
}

int main(void)
{
char *nn = 0;
a(&nn);
if (nn)
printf("nn points to \"%s\",\n nn[5] = %c\n", nn, nn[5]);
free(nn);
return 0;
}

[output]
nn points to "abcedef",
nn[5] = e
 
C

Christopher Benson-Manica

Joel said:
getchI() wont work with these 3 headers only.

It is proper Usenet etiquette to include the relevant portions of the text
you are replying to. To do this using Google groups, please follow the
instructions below, penned by Keith Thompson:

If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.
 
F

Frodo Baggins

Hrv'uljak said:
Anybody has a better solution? How to avoid memory allocation in main
function?

Thanks!

--------
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <malloc.h>

int a(char *n) {
n=(char *)realloc(n, 10);
strcpy(n, "abcdefg");
return 0;
}

int main()
{
char *nn=0;
nn=(char *)malloc(1);

a(nn);

printf("%c", nn[5]);

getch();
return 0;
}

What about free(), my sweetums?
Even if the calls to malloc(),realloc() were off the mark,
as a disciplined programmer, neglecting to free() your memory is not
right.

Regards,
Frodo Baggins
 
M

Martin Ambuhl

Joel said:
getchI() wont work with these 3 headers only.

Since your headers refer to my message
<[email protected]>, I assume your
contextless randomness is meant in reply to my posting.

In that posting, the "3 headers" are
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

There is, of course, no such thing as a standard function getchI(). Nor
is there such a thing as a standard function getch() which Hrv'uljak had
in his code. I suppose you think that the non-standard header <conio.h>
is needed.
1) There is no need for some non-standard function getch() for this program.
2) getch() comes in many flavors. My getch() is prototyped in
<curses.h>, for example. It almost certainly has different properties
from the one for which you think <conio.h> is needed.
3) There is *no* standard covering what functionality <conio.h> gives
access to.

Since attempts to include <conio.h> or attempts to use either getch() or
getchI() may make this code uncompilable for many perfectly good C
implementations, you need a damn good reason to use them. And this code
has *no* reason at all for using them.
 
J

Joe Estock

Hrv'uljak said:
Anybody has a better solution? How to avoid memory allocation in main
function?

Thanks!
My replies are inline below.
--------
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <malloc.h>

int a(char *n) {
n=(char *)realloc(n, 10);
strcpy(n, "abcdefg");
return 0;
}
int a(char *n)
{
char *tmp;

if(n == NULL)
{
if((n = malloc(10)) == NULL)
{
fprintf(stderr, "%s:%d: call to malloc returned NULL\n", __FILE__,
__LINE__);
}
}
else
{
/* always ALWAYS test your calls to realloc */
if((tmp = realloc(n, 10)) == NULL)
fprintf(stderr, "%s:%d: call to realloc returned NULL\n", __FILE__,
__LINE__);
else
n = tmp;
}

strcpy(n, "abcdefg");

return(0); /* we could return the amount we [re]allocated instead */
}
int main()
{
char *nn=0;
nn=(char *)malloc(1);

a(nn);

printf("%c", nn[5]);

getch();
return 0;
}
int main(int argc, char **argv)
{
char *nn = NULL; /* NULL might not be 0 on some systems */

a(nn);

printf("%c\n", nn[5]);

/* personal preference */
printf("Press any key to continue...");
getch();

/* not doing this might be a bad idea (tm) */
free(nn);

return(EXIT_SUCCESS);
}

-Joe
 
F

Flash Gordon

Joe said:
My replies are inline below.


int a(char *n)
{

n is passed by value so any changes to it, such as when you call
malloc/realloc won't be passed back to the calling function.
char *tmp;

if(n == NULL)
{

There is no point in this. If n is a null pointer then you can pass it
to realloc and realloc will do the same as malloc. This greatly
simplifies your code.
if((n = malloc(10)) == NULL)
{
fprintf(stderr, "%s:%d: call to malloc returned NULL\n", __FILE__,
__LINE__);
}
}
else
{
/* always ALWAYS test your calls to realloc */
if((tmp = realloc(n, 10)) == NULL)
fprintf(stderr, "%s:%d: call to realloc returned NULL\n", __FILE__,
__LINE__);
else
n = tmp;
}

strcpy(n, "abcdefg");

If you've failed the malloc or realloc then you should not copy the
string in since you don't have the expected space.
return(0); /* we could return the amount we [re]allocated instead */

Now you've just lost your only pointer to the allocated space (unless it
hit the realloc and the realloc failed.

return is not a function so you don't need parenthesis, "return 0;"
would be valid.

Why return a value at all when it is always the same value? Why not make
it a void function?
}
int main()
{
char *nn=0;
nn=(char *)malloc(1);

a(nn);

printf("%c", nn[5]);

getch();
return 0;
}
int main(int argc, char **argv)
{
char *nn = NULL; /* NULL might not be 0 on some systems */

In your source code 0 is always a valid null pointer constant. It's just
the bit representation of the null pointer that might not be all bits
zero when the program is run, but as long as you don't use tricks (such
as memset to initialise a pointer) this is not a problem.
a(nn);

printf("%c\n", nn[5]);

Did you actually try this? I think not.
/* personal preference */
printf("Press any key to continue...");
getch();

People have commented on this type of thing many times in the past. It's
not needed and an annoyance to some people.
 
J

Joe Estock

Flash said:
n is passed by value so any changes to it, such as when you call
malloc/realloc won't be passed back to the calling function.
The result of late-night usenet replying. The prototype *should* have
been int a(char **n);
There is no point in this. If n is a null pointer then you can pass it
to realloc and realloc will do the same as malloc. This greatly
simplifies your code.
Agreed. I keep forgetting that realloc can be passed a NULL pointer.
If you've failed the malloc or realloc then you should not copy the
string in since you don't have the expected space.
Again, the result of a late-night reply. I meant to add return(-1); in
the apropriate places above.
return(0); /* we could return the amount we [re]allocated instead */


Now you've just lost your only pointer to the allocated space (unless it
hit the realloc and the realloc failed.

return is not a function so you don't need parenthesis, "return 0;"
would be valid.
Personal preference. I know they are not needed, however I prefer to use
them. To me it's much like the age old void foo() { and void voo()\n{
complaint - use whatever you're comfortable with.
Why return a value at all when it is always the same value? Why not make
it a void function?
Again, I agree with you in the above code. I feel that OP should return
the amount of memory malloc'ed if this is the route OP is going to go.
int main()
{
char *nn=0;
nn=(char *)malloc(1);

a(nn);

printf("%c", nn[5]);

getch();
return 0;
}
int main(int argc, char **argv)
{
char *nn = NULL; /* NULL might not be 0 on some systems */


In your source code 0 is always a valid null pointer constant. It's just
the bit representation of the null pointer that might not be all bits
zero when the program is run, but as long as you don't use tricks (such
as memset to initialise a pointer) this is not a problem.
Completeness is never wrong. You should always use NULL instead of a
hard-coded value. Again, personal preference I suppose.
a(nn);

printf("%c\n", nn[5]);


Did you actually try this? I think not.
No, I did not. Again, it was a late-night reply and not very well
thought out it would seem ;)
People have commented on this type of thing many times in the past. It's
not needed and an annoyance to some people.
Yes, I agree however the OP was doing the same thing therefore I kept it
along the same path as him, the only difference is my added printf
statement.

-Joe
 
J

Joe Estock

Martin said:
Some people just refuse to learn a damn thing, don't they?
I don't use that code myself. It's unneeded since I'm on linux and
develop for linux (and linux-like) systems. I was simply adding the
"press any key to continue..." and keeping the functionality similar to
OP's.

-Joe
 
C

Christopher Benson-Manica

getch() is non-standard, and it's been pointed out enough that it's no
wonder Martin is getting a little prickly. Please stick to standard C
on this group and avoid the Noid.
 
F

Flash Gordon

Joe said:
Flash Gordon wrote:


Personal preference. I know they are not needed, however I prefer to use
them. To me it's much like the age old void foo() { and void voo()\n{
complaint - use whatever you're comfortable with.

I agree that it is a matter of style. When commenting on code I have a
habit on commenting on all aspects, including those of style. I prefer
"return 0;" to "return(0);" because it is fewer characters and I get a
far more helpful error for "retrun 0;" than I do for "retrun(0);".

Completeness is never wrong. You should always use NULL instead of a
hard-coded value. Again, personal preference I suppose.

I was commenting on your comment, not the code. I use NULL myself, but
it is important to know that for all implementation 0 is also valid, not
because you should use it but because so many other people *do* use it.

No, I did not. Again, it was a late-night reply and not very well
thought out it would seem ;)

We all make that mistake on occasion :)

Due to the lack of a /n or flushing stdout there is even less guarantee
than normal that it will be output before the next function call, line
buffering being fairly normal (and allowed by the standard) on stdout.
Yes, I agree however the OP was doing the same thing therefore I kept it
along the same path as him, the only difference is my added printf
statement.

Around here, it would be advisable to not post non-standard C, at least
without appropriate disclaimers and pointing people else where for
discussing it, or you *will* get people pulling you up on it.

As others have suggested in the past, if one *really* wants to do
something like that then the portable solution is a loop reading
characters waiting for a newline, for anything else a non-standard
solution is required and such solutions do not belong on this group.
 
E

Emmanuel Delahaye

Marc Boyer a écrit :
What about this ?

char* a(){

Better to stick to the prototype form.

char* a(void)
char* res= malloc( sizeof("abcdef") );
if (res)
strcpy(res, "abcdef");
return res;
}

int main(){
char *nn= a();
if (nn)
printf("%c", nn[5]);

a fflush (stdout) or a '\n' is missing...

a free(nn) is missing...
return nn!=NULL;

nn!=NULL; can return 1 which is not a portable value.
 

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

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,608
Members
45,249
Latest member
KattieCort

Latest Threads

Top