Skip to contentSkip to conversation

malloc(1/0) ??

DISCUSSION RAJESH BALAN 10 participants 16 messages Nov 7, 2000 – Nov 9, 2000

lore
Share & tools
lore
#0 lore raw

hi,
why does this program works. when executed, it doesnt give a segmentation fault. when the program requests memory, is a standard chunk is allocated irrespective of the what the user specifies. please explain.

main()
{
char *s;
s = (char*)malloc(0);
strcpy(s,"fffff");
printf("%s\n",s);
}

NOTE:
i know its a 'C' problem. but i wanted to know how
this works

__________________________________________________
Do You Yahoo!?
Thousands of Stores. Millions of Products. All in one Place.
http://shopping.yahoo.com/
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#1 lore raw
Quoted 14 lines

hi,
why does this program works. when executed, it doesnt give a segmentation fault. when the program requests memory, is a standard chunk is allocated irrespective of the what the user specifies. please explain.

main()

{
   char *s;
   s = (char*)malloc(0);
   strcpy(s,"fffff");
   printf("%s\n",s);
}
Quoted 3 lines

NOTE:
i know its a 'C' problem. but i wanted to know how
this works

The program does not work. A program works if it does what it's supposed to
do. If you want to argue that this program is supposed to print "ffffff" then explain to me why the 'malloc' contains a zero in parenthesis.

The program can't possibly work because it invokes undefined behavior. It
is impossible to determine what a program that invokes undefined behavior is 'supposed to do'.

DS

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#2 lore raw

When a program does a malloc... the glibc gets atleast on page (brk) [actually, glibs determins of it needs to brk more memory from the kernel... because it maintains it;s own pool].. so if you malloc 4 byts, you can copy to that pointer more than 4 bytes (upto a page size, ex 4K)... hope that answers one of your questions... as far as why malloc(0) works... I dunno

Best Wishes,
Lyle
----- Original Message -----
From: "David Schwartz" <[email protected]>
To: "RAJESH BALAN" <[email protected]>; <[email protected]>
Sent: Monday, November 06, 2000 11:54 PM
Subject: RE: malloc(1/0) ??

Quoted 14 lines
Quoted 14 lines

hi,
why does this program works. when executed, it doesnt give a segmentation fault. when the program requests memory, is a standard chunk is allocated irrespective of the what the user specifies. please explain.

main()

{
   char *s;
   s = (char*)malloc(0);
   strcpy(s,"fffff");
   printf("%s\n",s);
}
Quoted 5 lines
Quoted 3 lines

NOTE:
i know its a 'C' problem. but i wanted to know how
this works

The program does not work. A program works if it does what it's supposed

to

Quoted 5 lines

do. If you want to argue that this program is supposed to print "ffffff" then explain to me why the 'malloc' contains a zero in parenthesis.

The program can't possibly work because it invokes undefined behavior. It is impossible to determine what a program that invokes undefined behavior

is

Quoted 9 lines

'supposed to do'.

DS

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#3 lore raw
Quoted 5 lines · Lyle Coder

When a program does a malloc... the glibc gets atleast on page (brk) [actually, glibs determins of it needs to brk more memory from the kernel... because it maintains it;s own pool].. so if you malloc 4 byts, you can copy to that pointer more than 4 bytes (upto a page size, ex 4K)... hope that answers one of your questions... as far as why malloc(0) works... I dunno

Hmm.. Don't read a manpage in the middle of the night.. the issue is only with realloc(0) that is equal to free().

Maybe one of the glibc guys can tell what the behaviour is with malloc(0).

Quoted 2 lines

Best Wishes,
Lyle

Igmar

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#4 lore raw
In reply to David Schwartz

Hello ,

Quoted 13 lines
Quoted 13 lines

why does this program works. when executed, it doesnt give a segmentation fault. when the program requests memory, is a standard chunk is allocated irrespective of the what the user specifies. please explain.

main()

{
   char *s;
   s = (char*)malloc(0);
   strcpy(s,"fffff");
   printf("%s\n",s);
}
Quoted 3 lines
Quoted 3 lines

NOTE:
i know its a 'C' problem. but i wanted to know how
this works

C problem? You would better say , library problem(but it's not a problem at all).

Quoted 7 lines

The program does not work. A program works if it does what it's supposed to do. If you want to argue that this program is supposed to print "ffffff" then explain to me why the 'malloc' contains a zero in parenthesis.

The program can't possibly work because it invokes undefined behavior. It is impossible to determine what a program that invokes undefined behavior is 'supposed to do'.

I dont think it's undefined behaviour ...

Text from malloc.c <glibc2.something>
<------snip-------->
Malloc Algorithm:

The requested size is first converted into a usable form, `nb'. This currently means to add 4 bytes overhead plus possibly more to obtain 8-byte alignment and/or to obtain a size of at least MINSIZE (currently 16, 24, or 32 bytes), the smallest allocatable size. (All fits are considered `exact' if they are within MINSIZE bytes.)
<----- snip --------->
So some area of MINSIZE is alloced , and you can write there... Problems will arrive with writing over this area, and overwriting next memory chunk header. Write is not a problem ... in your code you have 4KB to spare, but when you try to free() you'd probably get SIGSEG.

Hope that you have idea how it works now. If not, read the malloc.c comments to find about about how malloc realy works.

Adino

Signature · 7 lines
/* Andrej Hosna - http://people.ibl.sk/adino - +421 903 852 696  */
/* IBL Software Engineering - http://www.ibl.sk - +421 7 43427214 */
                                                                
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#5 lore raw
Quoted 8 lines
Quoted 2 lines

The program can't possibly work because it invokes undefined

behavior. It

Quoted 1 line

is impossible to determine what a program that invokes

undefined behavior is

Quoted 1 line

'supposed to do'.

I dont think it's undefined behaviour ...

You are correct. This is bahavior that is undefined by the C language, but
defined by the implementation. So determining what the program was supposed to do requires determining whether the person who wrote it was familiar with the implementation on which it is being used. Amusingly, this means the program is supposed to do different things depending upon what implementation of malloc you have.

IIRC, malloc(0) is defined to return a unique block of memory that it is
valid to pass to free. However, doing anything with this memory (read/write) is undefined by the C standard.

DS

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#6 lore raw
In reply to David Schwartz
Quoted 5 lines · Lyle Coder

When a program does a malloc... the glibc gets atleast on page (brk) [actually, glibs determins of it needs to brk more memory from the kernel... because it maintains it;s own pool].. so if you malloc 4 byts, you can copy to that pointer more than 4 bytes (upto a page size, ex 4K)... hope that answers one of your questions... as far as why malloc(0) works... I dunno

Maybe following extract from glibc's malloc/malloc.c beginning comments can help you there:

Minimum overhead per allocated chunk: 4 or 8 bytes
Each malloced chunk has a hidden overhead of 4 bytes holding size and status information.

Minimum allocated size: 4-byte ptrs: 16 bytes (including 4 overhead)
8-byte ptrs: 24/32 bytes (including, 4/8 overhead)

When a chunk is freed, 12 (for 4byte ptrs) or 20 (for 8 byte ptrs but 4 byte size) or 24 (for 8/8) additional bytes are needed; 4 (8) for a trailing size field
and 8 (16) bytes for free list pointers. Thus, the minimum allocatable size is 16/24/32 bytes.

Even a request for zero bytes (i.e., malloc(0)) returns a pointer to something of the minimum allocatable size.

Maximum allocated size: 4-byte size_t: 2^31 - 8 bytes

                          8-byte size_t: 2^63 - 16 bytes

Other systems (malloc libraries) may have different strategies on this allocation management issue, thus allocating anything smaller than the
needed size is bound to get user burned. malloc(0) is insane thing
(IMO), but at least glibc supports it for some reason. Likely just due to padding and minimum size issues.

Quoted 2 lines

Best Wishes,
Lyle

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#7 lore raw
Quoted 3 lines · Matti Aarnio

needed size is bound to get user burned. malloc(0) is insane thing
(IMO), but at least glibc supports it for some reason. Likely just due to padding and minimum size issues.

Part of the desing of the C language and the library is intended to make boundary conditions go well automatically.

So, a program that does:

	fscanf (file, "%d", &numsquares);
	squares = malloc (sizeof (struct square) * numsquares);
	for (i=0;i<numsquares; i++)
	   read_square_from_file (file, &squares[i]);

	fscanf (file, "%d", &numtriangles);
	triangles = malloc (sizeof (struct triangle) * numtriangles);
	for (i=0;i<numtriangles; i++)
	   read_triangle_from_file (file, &triangles[i]);


	[use the stuff....]

	free (triangles);
	free (squares);

should work. See, the "for" loop nicely executes 0 times when numtriangles is zero. Similarly, malloc/free don't have any "exception" case for the "numtriangles is zero" case.

Now, at first you might say that "malloc" could return NULL, as long as "free" accepts it. However, that's not true: The result of the malloc call can and acutally should be checked for "NULL", and the program might abort.

A valid implementation MAY:

	#define NIL ((void *) 1)

	void * malloc (int size)
	{
	if (size == 0) NIL;
	[....]
	}

	void free (void *ptr)
	{
	if (ptr == NIL) return;
	[...]
	}

This way all should work. However someone mentioned that the returns from "malloc" should be unique. Why would that be? That would prohibit my "1" trick. The statement implies you want to go about checking pointers for equality. If for example you have a memcmp (a, b) that has "if (a == b) return 0;" at the beginning. That would be allowed for the NIL pointers. (all malloc-0 results SHOULD compare equal
anyway: there are 0 differences....)

Roger.

Signature · 8 lines
** [email protected] ** http://www.BitWizard.nl/ ** +31-15-2137555 **
*-- BitWizard writes Linux device drivers for any device you may have! --*
*       Common sense is the collection of                                *
******  prejudices acquired by age eighteen.   -- Albert Einstein ********
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#8 lore raw
Quoted 8 lines

This way all should work. However someone mentioned that the returns from "malloc" should be unique. Why would that be? That would prohibit my "1" trick. The statement implies you want to go about checking pointers for equality. If for example you have a memcmp (a, b) that has "if (a == b) return 0;" at the beginning. That would be allowed for the NIL pointers. (all malloc-0 results SHOULD compare equal
anyway: there are 0 differences....)

It's a SuSv2 thing:

"Upon successful completion with size not equal to 0, malloc() returns a pointer to the allocated space. If size is 0, either a null pointer or a unique pointer that can be successfully passed to free() will be returned. Otherwise, it returns a null pointer and sets errno to indicate the error."

DS

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#9 lore raw
In reply to David Schwartz
Quoted 8 lines

The program does not work. A program works if it does what it's supposed to
do. If you want to argue that this program is supposed to print "ffffff" then explain to me why the 'malloc' contains a zero in parenthesis.

The program can't possibly work because it invokes undefined behavior. It
is impossible to determine what a program that invokes undefined behavior is 'supposed to do'.

May I remind you guys that a malloc(0) is equal to a free(). There is no way that any mem get's malloced.

You only get a coredump if the program accesses a page it shouln't, and since whe're talking 5 bytes here or so, you have a change that you don't cross a boundary.

Quoted 1 line

DS

Igmar

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#10 lore raw
In reply to David Schwartz
Followup to:  <[email protected]>
By author:    Igmar Palsenberg <[email protected]>
In newsgroup: linux.dev.kernel
Quoted 6 lines
Quoted 6 lines

The program does not work. A program works if it does what it's supposed to
do. If you want to argue that this program is supposed to print "ffffff" then explain to me why the 'malloc' contains a zero in parenthesis.

Quoted 7 lines
Quoted 3 lines

The program can't possibly work because it invokes undefined behavior. It
is impossible to determine what a program that invokes undefined behavior is 'supposed to do'.

May I remind you guys that a malloc(0) is equal to a free(). There is no way that any mem get's malloced.

Where the heck did you get idea?

-hpa

Signature · 7 lines
<[email protected]> at work, <[email protected]> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#11 lore raw
Quoted 2 lines

Where the heck did you get idea?

By reading the man page in the middle of the night and reading realloc() as malloc().

My error.

Quoted 1 line

-hpa

Igmar

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#12 lore raw
In reply to David Schwartz
Quoted 3 lines · H. Peter Anvin
Followup to:  <[email protected]>
By author:    Igmar Palsenberg <[email protected]>
In newsgroup: linux.dev.kernel

[snip]

Quoted 7 lines
Quoted 3 lines

May I remind you guys that a malloc(0) is equal to a free(). There is no way that any mem get's malloced.

Where the heck did you get idea?

-hpa

Probably from the malloc man page where it is stated that *realloc* with size 0 equals free :)

Signature · 8 lines
        Rasmus([email protected])

Which is worse: Ignorance or Apathy?
Who knows? Who cares?
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#13 lore raw
In reply to RAJESH BALAN
Quoted 10 lines · RAJESH BALAN

hi,
why does this program works. when executed, it doesnt give a segmentation fault. when the program requests memory, is a standard chunk is allocated irrespective of the what the user specifies. please explain.

main()

{
   char *s;
   s = (char*)malloc(0);

malloc(0) is bogus in this case. malloc(0) == free();

Quoted 7 lines
   strcpy(s,"fffff");
   printf("%s\n",s);
}

NOTE:
i know its a 'C' problem. but i wanted to know how
this works

The most plausible reason is you're not crossing a page boundary, and you don't get a access violation.

Igmar

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#15 lore raw
Quoted 5 lines · Tim Waugh
Quoted 1 line · Igmar Palsenberg

malloc(0) is bogus in this case. malloc(0) == free();

No, you're thinking of realloc.

Yep. My error. Sorry.

Igmar

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/