char *ptr="Is memory allocated here?" 
Author Message
 char *ptr="Is memory allocated here?"

I have three questions regarding memory allocation:

char *ptr="some stupid string";
char array[]="some stupid string";

First, when a char pointer is initialized with a string, is sufficient
memory allocated?  Aside from "ptr" being an lvalue, while "array" is
only an rvalue, is there any other difference between "ptr" and "array"?

void foo(char *ptr);      // function prototype

void main(void)
{
        foo("literal string");

Quote:
}

Second, what happens when a literal string is passed to a function
expecting a char pointer? My best guess is that "literal string"
goes on the stack, and "ptr" is initialized to the former stack
base. Is this right?

Last, I have written programs which (successfully) use free() to
release calloc()'d memory (as opposed to using cfree() to release
the memory). What are the differences between these two functions?
I believe that calloc() is nearly identical to (and probably uses)
malloc(), so is this practice really acceptable?

Thanks alot.




Sat, 02 Apr 1994 23:05:47 GMT  
 char *ptr="Is memory allocated here?"

Quote:
>I have three questions regarding memory allocation:
>char *ptr="some stupid string";
>char array[]="some stupid string";
>First, when a char pointer is initialized with a string, is sufficient
>memory allocated?  Aside from "ptr" being an lvalue, while "array" is
>only an rvalue, is there any other difference between "ptr" and "array"?
>void foo(char *ptr);      // function prototype
>void main(void)
>{
>    foo("literal string");
>}
>Second, what happens when a literal string is passed to a function
>expecting a char pointer? My best guess is that "literal string"
>goes on the stack, and "ptr" is initialized to the former stack
>base. Is this right?

Apart from when an array is initialised, all references to a string
cause a static copy of that string to be stored somewhere in memory
and the string in the source, er, sort of, replaced by a pointer to
the first character of the string.

So in your first example, the string is put somewhere [it doesn't
matter where, but it generally wont get erased] and ptr is
initialised with a pointer to the first character of the string,
whereas for the array the individual elements of the array are
intialised with the characters of your string.  

In the second, a STATIC copy of the string is stored at compile
time somewhere in your program, and code is compiled to pass
a pointer to the first character of "literal string" to foo().
Strings are not generally pushed on and off stacks, except when
initialising auto (the default storage for local variables)
character arrays in ANSI C. I hope that answers your question.
If foo actually changes a character in your string, then the
next time that actual statement is re-run, the revised string
will be passed to foo().

Quote:
>Last, I have written programs which (successfully) use free() to
>release calloc()'d memory (as opposed to using cfree() to release
>the memory). What are the differences between these two functions?
>I believe that calloc() is nearly identical to (and probably uses)
>malloc(), so is this practice really acceptable?

cfree() and free(): not much except that cfree() isn't in the ANSI
library, so use free().
malloc() and calloc(): these are similar, malloc allocates bytes
whereas calloc allocates units. malloc needs one parameter, being
the number of bytes. calloc needs two: the size of each unit in
bytes and the number of units. So if you wanted to allocate space
for a [sorry, read 'char's, not 'byte's.] hundred chars, you'd
write   ptr = malloc(100)

But if you wanted to allocate space for 100 long ints, you'd write:
        ptr = calloc(sizeof(long int), 100)

I may have got the parameters the wrong way round for calloc(), but
in practise it rarely matters as calloc usally looks like this:

void /* or char in K&R C */ *calloc(us,no)
int us,no;
{
        return malloc(us*no);

Quote:
}
>Thanks alot.

You're welcome.

Paul Harrison

[Opinions are mine, not UEA's]



Sun, 03 Apr 1994 01:58:16 GMT  
 char *ptr="Is memory allocated here?"

: I have three questions regarding memory allocation:
:
:
: char *ptr="some stupid string";
: char array[]="some stupid string";
:

Related to this question is the old 'what happens if I have an array
allocated in one file, and give an extern reference as a POINTER in
another source file?'

$ cat 1.c
char array[1024];
$ cat 2.c
extern char *array;

file 2.c is incorrect.

$ cat 2.a.c
extern char array[];

is correct (assuming these 2 files are linked together).
--

Terry Gardner | The Home Depot, Inc. | One Paces West
2727 Paces Ferry Road, NW | Atlanta, GA
Voice (404)433-8211x5124



Sun, 03 Apr 1994 03:11:28 GMT  
 char *ptr="Is memory allocated here?"

Quote:
>I have three questions regarding memory allocation:
>char *ptr="some stupid string";
>char array[]="some stupid string";
>First, when a char pointer is initialized with a string, is sufficient
>memory allocated?  Aside from "ptr" being an lvalue, while "array" is
>only an rvalue, is there any other difference between "ptr" and "array"?

The string in *ptr is constant and most/all compilers will create it as
such. Thus, trying to write to it will be a Bad Thing. No such problems
with array since it is "kept" in "writable" storage and can be altered at
will (although if you write PAST the \0 after "string" Bad Things can
happen).

Quote:
>void foo(char *ptr);      // function prototype
>void main(void)
>{
>    foo("literal string");
>}
>Second, what happens when a literal string is passed to a function
>expecting a char pointer? My best guess is that "literal string"
>goes on the stack, and "ptr" is initialized to the former stack
>base. Is this right?

What the compiler actually does is to pass a pointer to that literal string.
In effect "a string" is a pointer to the string "a string". This makes sense
when you consider:

        char *cptr;
        cptr = "hello";

since cptr is a char pointer, "hello" must be also...

--
==============================================================================
#include <std/disclaimer.h>

           Jim Jagielski                    NASA/GSFC, Code 711.4

         "Ah! I see you have the machine that goes 'BING!'"



Sun, 03 Apr 1994 01:01:49 GMT  
 char *ptr="Is memory allocated here?"

|>
|> >I have three questions regarding memory allocation:

(Questions deleted her, not really relevant to this posting)

|> cfree() and free(): not much except that cfree() isn't in the ANSI
|> library, so use free().
|> malloc() and calloc(): these are similar, malloc allocates bytes
|> whereas calloc allocates units. malloc needs one parameter, being
|> the number of bytes. calloc needs two: the size of each unit in
|> bytes and the number of units. So if you wanted to allocate space
|> for a [sorry, read 'char's, not 'byte's.] hundred chars, you'd
|> write   ptr = malloc(100)
|>
|> But if you wanted to allocate space for 100 long ints, you'd write:
|>   ptr = calloc(sizeof(long int), 100)

Also, calloc is guaranteed to initialize the allocated space to all zeros,
whereas malloc does not. (The 'c' standing for 'clear' ?)

|>
|> I may have got the parameters the wrong way round for calloc(), but
|> in practise it rarely matters as calloc usally looks like this:

Yes, reverse the order, ptr = calloc(100, sizeof(ling int));

|> void /* or char in K&R C */ *calloc(us,no)
|> int us,no;
|> {
|>   return malloc(us*no);
|> }
|

More like

void *calloc(size_t nobj, size_t size)
{       void *ptr;

        ptr = malloc(nobj * size);
        if(ptr) memset(ptr, 0, nobj * size);

        return ptr;

Quote:
}

|> Paul Harrison
|>
|> [Opinions are mine, not UEA's]

Opinions are mine ?
------------------------------------------------------------



------------------------------------------------------------
"Ohm, sweet ohm"                                 (Kraftwerk)



Sun, 03 Apr 1994 19:49:42 GMT  
 char *ptr="Is memory allocated here?"

Quote:
(Sudheer Apte) writes:
>Actually, it only initializes the space to zero *bytes*, not zero
>int's or whatever.  So calloc() really isn't much use for allocating
>anything other than chars in practice.   (K&R2, p.252).

You can count that you will get zero integers on almost all machines
in the known universe (I know of none where this isn't true, but I'd
like to know what the ones that you can't).  However, you can't count
on it making pointers have the same value as if the integer constant
zero was assigned to them (or in other words, you can't count on the
pointers in your struct being NULL pointers).  THAT is what makes
calloc less useful than you might first thing upon reading its
description.

Warner
--

"Red hair is caused by sugar and lust," the woman, who was blond, confided.
"Highly evolved beings do not indulge in sugar and lust." -- Tom Robbins



Mon, 04 Apr 1994 09:46:05 GMT  
 char *ptr="Is memory allocated here?"

Quote:

> Also, calloc is guaranteed to initialize the allocated space to all zeros,
> whereas malloc does not. (The 'c' standing for 'clear' ?)

Actually, it only initializes the space to zero *bytes*, not zero
int's or whatever.  So calloc() really isn't much use for allocating
anything other than chars in practice.   (K&R2, p.252).

        Sudheer.
------------------
...{harvard, uunet}!andrew.cmu.edu!sa1z



Mon, 04 Apr 1994 00:03:04 GMT  
 char *ptr="Is memory allocated here?"

: I have three questions regarding memory allocation:
:
:
: char *ptr="some stupid string";
: char array[]="some stupid string";
:
: First, when a char pointer is initialized with a string, is sufficient
: memory allocated?  Aside from "ptr" being an lvalue, while "array" is
: only an rvalue, is there any other difference between "ptr" and "array"?
:
:
: void foo(char *ptr);      // function prototype
:
: void main(void)
: {
:       foo("literal string");
: }
:
: Second, what happens when a literal string is passed to a function
: expecting a char pointer? My best guess is that "literal string"
: goes on the stack, and "ptr" is initialized to the former stack
: base. Is this right?
:
: Last, I have written programs which (successfully) use free() to
: release calloc()'d memory (as opposed to using cfree() to release
: the memory). What are the differences between these two functions?
: I believe that calloc() is nearly identical to (and probably uses)
: malloc(), so is this practice really acceptable?
:
: Thanks alot.
:

In answer to your first question, most compilers should treat the
two strings identically (although I have used some cross compilers
which do not -- i.e. ASCII data gets pushed on the call stack
instead of the address of the string...), and if they don't, then
they (the compilers) are in error.  When you use a string literal
in a program, such as "some stupid string", the compiler will store
that data within the program, so no space needs to be "allocated" per
se;  rather, that string has an address in the program's data space.

Secondly, when you pass the literal string to a function expecting
a char pointer, nothing as elaborate as you have hypothesized happens.
The literal string (i.e. "literal string") will be put into the
program's data space (as above) and the address to that data space
will be passed to the function -- i.e. the function will get a char
pointer to the area that the compiler put your literal string into.
The thing to keep in mind is that unless your compiler is _VERY_
smart, each time you use a literal string space will be used for
it in the progam's data space, even if the strings are the same.  In
other words, if your function calls foo("literal string") three
different times, three separate instances of the string "literal
string" will exist in your program's data space, and foo will get
a different pointer value for each call.

Finally, memory allocation schemes are machine dependent.  However,
in most schemes that I have seen, calloc() will call malloc, and
then explicitly clear all of the bytes that you asked for.  Since
I am not familiar with cfree() (I think your compiler's libs may
have some non-standard extensions...), I can't comment too generally
on that.  But, given that most calloc's operate in the manner that
I have stated, then free() should work just fine.

You may wish to use your compiler's option to produce assembly
output in the future;  this way, you can see exactly what the
machine/program is doing.  Of course, you could always use the
#pragma dwim (do what I mean) :=)

---------------------------------------------------------------------
-Jefrem M. Iwaniw, Sr. Consultant, Pelican Software   0
"To know even one life has breathed easier because  _/ \
 you have lived;  This is to have succeeded."      (_)
                         -Ralph Waldo Emerson       |_
My own opinions, not my clients'.
---------------------------------------------------------------------



Tue, 05 Apr 1994 21:04:08 GMT  
 char *ptr="Is memory allocated here?"


Bossman> malloc() and calloc() are similar, except that calloc()
Bossman> actually clears the memory that is allocated to all zeros.
Bossman> This is very useful for allocating arrays of NULL pointers.


RE> Actually, it's quite useless for doing that.  All zeroes is not the
RE> same as a NULL pointer.

Well, if you accept K&R as an authority, you can assume that NULL
is the integer 0 as far as the compiler is concerned.  I'll quote
gratuitously:

K&R ed. 1 page 192:

Quote:
> ...it is guaranteed that assignment of the constant 0 to a
> pointer will produce a null pointer distinguishable from a
> pointer to any object.

K&R ed. 2 page 198

Quote:
> An integral constant expression with value 0, or such an
> expression cast to type void *, may be converted, by a cast, by
> assignment, or by comparison, to a pointer of any type.  This
> produces a null pointer that is equal to another pointer of the
> same type, but unequal to any pointer to a function or object.

This doesn't guarantee that the memory representation of this
pointer is zero, but it seems the obvious implementation is to
store null pointers just like the integer 0, i.e. as zeroed
memory.  While there are some who don't want to write code that
assumes anything but what's specified in either K&R I or the ANSI
standard, I think it's reasonable to initialize memory containing
NULL pointers with a direct memory manipulation function if it's
going to work on just about all the existing C compilers.  Library
functions and include files are much more likely to limit your code
than obscure compiler implementation details, in my experience,
which is admittedly limited to Unix and MessyDos systems.

Of course, it's possible there are a few compilers floating around
that don't store null pointers as zeroed memory.  I'm interested in
knowing if anyone out there finds one.

#include <stdio.h>

main() {
    char **p;

    p = (char **) calloc(1, sizeof(char *));
    if (*p == NULL) {
        puts("Zeroed memory functions as NULL pointer.");
    } else {
        puts("Zeroed memory does not function as NULL pointer.");
    }

Quote:
}

Incidentally, I saw someone printf(str); recently.  The specific
example had str as "foo\n" after preprocessing, which will work,
but in general, fputs(str, stdout); or printf("%s", str); is less
likely to cause conflicts and slightly faster.

Greg Hudson



Mon, 11 Apr 1994 11:56:43 GMT  
 char *ptr="Is memory allocated here?"

Quote:
>char *ptr="some stupid string";
>char array[]="some stupid string";
>First, when a char pointer is initialized with a string, is sufficient
>memory allocated?  Aside from "ptr" being an lvalue, while "array" is
>only an rvalue, is there any other difference between "ptr" and "array"?

Yes there is a difference between the first statement and the second one. FOr
the first statement, the C compiler will allocate space for the string in a
global pool of static string data. It then initialises 'ptr' to point to this
string. The array version however actually creates an array in your global
data segment (or on the stack) containing the data of the string.

Quote:
>void foo(char *ptr);      // function prototype
>void main(void)
>{
>    foo("literal string");
>}
>Second, what happens when a literal string is passed to a function
>expecting a char pointer? My best guess is that "literal string"
>goes on the stack, and "ptr" is initialized to the former stack
>base. Is this right?

No, this is incorrect. As in the first example, all literal string data is
placed into a global string pool by the compiler (which resides in the same
spot as your global variable data). It just passes a pointer to this literal
string to the function.

You have to be careful when using literal strings, since only enough space to
hold all of the string's data and the null terminator are alloccated by the
compiler, so if you attempt to concatenate another string to a literal string
(or use any function that adds characters to the string), you will actually
be overwriting other memory in your global data space. Thus if you wish to
add something to the end of the string "some stupid string", you would have
to do it like so:

char array[255] = "some stupid string";

...

        strcat(array," This is added!!");

Quote:
>Last, I have written programs which (successfully) use free() to
>release calloc()'d memory (as opposed to using cfree() to release
>the memory). What are the differences between these two functions?
>I believe that calloc() is nearly identical to (and probably uses)
>malloc(), so is this practice really acceptable?

malloc() and calloc() are similar, except that calloc() actually clears the
memory that is allocated to all zeros. This is very useful for allocating
arrays of NULL pointers. Apart from this, the function the same, and yes,
calloc() probably does call malloc(). Thus using free() to free the memory is
quite alright.

+------------------------------------------+----------------------------------+
| Kendall Bennett,                         | Internet:                        |



+------------------------------------------+----------------------------------+
| CoSysop (Bossman), PC Connection Australia:                  +61 3 688 0909 |
+-----------------------------------------------------------------------------+



Sun, 10 Apr 1994 09:47:37 GMT  
 char *ptr="Is memory allocated here?"

Quote:

> Bossman> malloc() and calloc() are similar, except that calloc()
> Bossman> actually clears the memory that is allocated to all zeros.
> Bossman> This is very useful for allocating arrays of NULL pointers.

> Actually, it's quite useless for doing that.  All zeroes is not the
> same as a NULL pointer.

> --


Is it really useless ? stdio.h normally defines NULL as 0. Surely all
that would be needed would be an appropriate cast to the type of
null pointer required.

John Boutland.



Mon, 11 Apr 1994 12:40:49 GMT  
 char *ptr="Is memory allocated here?"

Bossman> malloc() and calloc() are similar, except that calloc()
Bossman> actually clears the memory that is allocated to all zeros.
Bossman> This is very useful for allocating arrays of NULL pointers.

Actually, it's quite useless for doing that.  All zeroes is not the
same as a NULL pointer.

--



Sun, 10 Apr 1994 18:31:27 GMT  
 char *ptr="Is memory allocated here?"

Quote:


>> Actually, it's quite useless for doing that.  All zeroes is not the
>> same as a NULL pointer.
>Is it really useless ? stdio.h normally defines NULL as 0. Surely all
>that would be needed would be an appropriate cast to the type of
>null pointer required.

This keeps coming up, although it is addressed in the FAQ.

A null pointer might be represented by all bits zero, but it need not.

When assigning or casting a constant zero to a pointer, the compiler
is obligated to generate the correct representation for a null pointer
of that type -- which might or might not be all bits zero.

So, if T is a some type,

        /* p becomes a null pointer of type T* */
        T* p = 0;

        /*  p gets all bits zero, which might not be a null pointer */
        T* p = calloc(1, sizeof(T*));

        /*  p gets all bits zero, which might not be a null pointer */
        int i = 0;
        T* p = i;       /* 'i' is not a constant zero */
--




Mon, 11 Apr 1994 23:54:45 GMT  
 char *ptr="Is memory allocated here?"

Quote:
>    /*  p gets all bits zero, which might not be a null pointer */
>    int i = 0;
>    T* p = i;       /* 'i' is not a constant zero */

Actually, the contents of p are implementation-dependent in this case.  The
results of conversions between integer and pointer types are undefined, and
aren't even required to return the original integer if the inverse
conversion is later performed on the result.  There's no rule that says
that the bits of the integer are copied into the bits of the pointer.
--
Barry Margolin, Thinking Machines Corp.


{uunet,harvard}!think!barmar



Tue, 12 Apr 1994 02:41:16 GMT  
 char *ptr="Is memory allocated here?"

Quote:


>Bossman> malloc() and calloc() are similar, except that calloc()
>Bossman> actually clears the memory that is allocated to all zeros.
>Bossman> This is very useful for allocating arrays of NULL pointers.


>RE> Actually, it's quite useless for doing that.  All zeroes is not the
>RE> same as a NULL pointer.

>Well, if you accept K&R as an authority, you can assume that NULL
>is the integer 0 as far as the compiler is concerned.  I'll quote
>gratuitously:

No, if you accept K&R as an authority, you can assume that a CONSTANT
0, that is, the ASCII character 0 appearing in the source code, will
be turned into whatever representation is required for a null pointer
in the object segment.  And (from your second quote) that a CONSTANT
expression with value 0 will be similarly converted by the compiler.

Quote:
>This doesn't guarantee that the memory representation of this
>pointer is zero, but it seems the obvious implementation is to
>store null pointers just like the integer 0, i.e. as zeroed
>memory.  

This may be 'obvious', but it is also WRONG, and assuming it will
get you in trouble.  I've used several machines in the recent past in
which it is NOT true, and where assuming it will NOT work.  The
last time we had this discussion, other people listed even more
machines than I'd have dreamed possible for which this will not work.
If you do it, it will come back to haunt you.

Quote:
>Of course, it's possible there are a few compilers floating around
>that don't store null pointers as zeroed memory.  I'm interested in
>knowing if anyone out there finds one.

There are LOTs of them.


Mon, 11 Apr 1994 23:53:40 GMT  
 
 [ 24 post ]  Go to page: [1] [2]

 Relevant Pages 

1. "memory clobbered before allocated block"...?

2. Error "free"-ing "malloc"-ed memory

3. Char *ptr="is Me

4. Function ptr equivalent of "NULL"?

5. printf("%p\n",(void *) ptr);

6. "No memory" while plenty of memory

7. Free a "2D dynamically allocated array"

8. Allocating "Space"

9. I am going to study "C"

10. Reg.allocating memory for double char pointer(char ** buf)

11. Why cast to (char *) before de-allocating memory in "Numerical Recipes in C" ?

12. char foo[]=""; vs char* foo="";

 

 
Powered by phpBB® Forum Software