Thread: malloc problem

  1. #1
    Registered User
    Join Date
    Apr 2003
    Posts
    18

    Unhappy malloc problem

    Hi, I need to modify a set of codes (f77, f90 and c codes) for the 64-bit archtecture on Sun (SPARC v9) in a 64-bit Solaris operating environment. So, C data type may need conversion, for example,

    (1) a fortran 77 code calls a C function mallocf:

    pointer (pptr,prolog)
    integer*8 prolog(*)
    integer*8 block_bytes
    block_bytes=100
    ...

    pptr = mallocf(block_bytes)
    ...

    (2) This is the c function (written for a 32-bit system):
    1
    2 long int mallocf_(nwords)
    3 long int *nwords;
    4 {
    5
    6 long int iptout;
    7 int nbytes;
    8
    9 nbytes = (*nwords);
    10 if(!(iptout= malloc(nbytes))) {
    11 printf("MALLOCF: Out of memory.\n");
    12 exit(1);
    13 }
    14
    15 return iptout;
    16
    17 }
    18

    This will work for a 32-bit arthetecture, but not for a 64-bit system the data size (long int) has increased to 8 bytes, but int is still 4 bytes.

    I made the below change:

    if(!(iptout=malloc(sizeof(*nwords)))) { ...

    however, malloc is implicitly declared to return int (4 bytes) while the long integer iptout is 8 bytes. How do I change the prototype for malloc?

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    malloc() returns type "void*", which is 8 bytes on a 64bit system.
    malloc() takes a parameter that specifies the number of bytes to allocate.

    I can't help you with the fotran part, but I do know that a word is 2 bytes. So if someone wants 4 words of memory, then malloc() should request 8 bytes.

    Since the fortran code uses "block_bytes" and the C code has "nbytes = (*nwords);", then I'll assume that "nwords" is just a bad (and misleading) variable name.

    Having said all that, I don' t see anything wrong with the C code you posted, other than the bad variable name. It is also a good idea to compare the return value of malloc() with NULL.

    gg

  3. #3
    Registered User
    Join Date
    Apr 2003
    Posts
    18
    Yes, you're right -- the nwords is indeed misleading -- it's someone else's code which I don't want to change the variable names. In case I get to talk to the person who wrote it ...

    I thought I got the earlier code wrong because I used lint:
    > lint mallocf2.c

    implicitly declared to return int
    (12) malloc (13) printf (14) exit
    value type used inconsistently
    malloc llib-lc:stdlib_iso.h(105) void *() :: mallocf2.c(6) int ()

    However, if I use malloc64, then lint issues no such inconsistency warning.

    By the way, what's the difference of returning a pointer like:
    if(!(iptout= malloc(nbytes))) {...

    verse a NULL pointer? I thought if if(!(iptout= malloc(nbytes))) is true, then iptout is NULL ...

    A furter question: When I use man to look at malloc, it says that

    malloc or malloc64 are Fortran library routines, then why use a C code to call a Fortran function? Are there other C-malloc that I don't know where to look for?

    Thanks!

  4. #4
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Do you have "#include <stdlib.h>" in that file? Lint is just saying that malloc() returns a void* and you are using it as a "long int".

    However, if I use malloc64, then lint issues no such inconsistency warning.
    I'm confused, malloc64 is a Fortran function...I don't know of a malloc64 in C.

    NULL isn't defined as 0 on some systems (although I've never seen it and it may not be true anymore) - so its a good habit to always campare with NULL instead of 0 (for portability).

    malloc or malloc64 are Fortran library routines, then why use a C code to call a Fortran function? Are there other C-malloc that I don't know where to look for?
    You mean "why have Fortran code call into C code when Fortran has its own version of malloc and malloc64?" - good question.

    Remember, when you see C code calling malloc() - it is calling the C version of the function not Fortran's version. From the code you posted, the Fortran code is calling mallocf, which (I assume) calls into the C function mallocf_().

    gg

  5. #5
    Registered User
    Join Date
    Apr 2003
    Posts
    18
    "You mean "why have Fortran code call into C code when Fortran has its own version of malloc and malloc64?" - good question."

    Exactly! The code that I'm trying to make it work for a 64-bit Solar was written by a group of people a long time ago (I pressume) for an arthitecture unknown to me... which probably did not have any fortran 77 versions of malloc (?), thus the extra trouble of calling a C function which calls C's own malloc... But now the machine I'm working on has it's own fortran library that includes such functions. The C function mallocf() does not have any include files -- so I hope it will call its own version of malloc correctly?! It's such a headache dealing with these "legacy" codes!

    I've tried to compile my code with Solaris 64-bit flags, but got a "segmentation fault", which dbx tells me that:

    signal SEGV (no mapping at the fault address) in mm_new_ad at line 970 in file "mm2000.f"
    970 link(j) = j + 1

    This is the piece of code (Fortran code):
    lptr = mallocf (max_ad*BYTES_PER_INT)
    do j = max_ad_orig + 1, max_ad - 1
    link(j) = j + 1 !line 970
    end do

    The j, max_ad_orig + 1, max_ad - 1 and lptr all have valid values at the point of crashing:
    (/opt/SUNWspro/bin/../WS6U2/bin/sparcv9/dbx) p lptr
    lptr = 1277248LL

    ,therefore there is something wrong with link which is defined as
    pointer (lptr, link)
    integer link(*)

    What does signal SEGV mean? Some other times I got "bus error"? I don't understand the meanings of these messages - thus have no idea what to check for! How do you check for errors that seem to indicate pointer problems?

    Well, I'm not a major in computer science, and become quite frustrated when I encounter these issues. Are there any good books or online tutorial that teach people how to handle these programming mechanics for scientists and engineers?

    Thanks again!!

  6. #6
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    SEGV means you are accessing memory that does not belong to you. Bus Error means you are accessing memory in an unaligned fashioned - whether it belongs to you or not.

    I don't know much Fortran so I won't be much help there. The only thing I can suggest is to ensure "BYTES_PER_INT" is correct for that code/compiler in a 64bit environment.

    CS majors become quite frustrated they encounter these issues too!

    gg

  7. #7
    Registered User
    Join Date
    Apr 2003
    Posts
    18
    Thanks for the reply. I just learned C last week following a tutorial - there is still much more to learn before I can properly understand these pointer problems. For example,

    char *p;
    char x;
    p=&x;

    float *q;
    float y;
    q=&y;

    When pointers are declared to point to some variable (int, float, char, etc), the pointer themselves are stored in memory too, and the values of the pointers are actually the address of the variables they point to. A dereferenced pointer *p will be equvalent to x which is a 1 byte character; *q is a 4 byte float (=y). But the pointer themselves (p and q) are stored as 4 byte (32-bit system) or 8 byte (64-bit system) numbers that represent memory address. Would you call these pointer numbers integer or something else? What is a proper way to display them?
    What is a unique memory address -- one byte? Then a 32-bit integer will be represented by 4 memory addresses? If an integer pointer ptr points to this integer variable, will ptr have the address of the first byte of this integer number (assuming one byte is one memory address)?

    The reason I'm converting a 32-bit code to 64-bit is to use more memory. The current code (compiled for 32-bit system) can only use up to 2 gb of memory. I've been thinking that since a 64-bit pointer has 2^64 possible bit patterns --> contain 2^64 distinct memory addresses, which means along with malloc, 2^64 (bytes)can be allocated (assuming one address for every byte)?

    Any enlightment is much welcome!

    I also learned to use emacs last week (a step moving away from Windows towards Unix system!) and have been typing sample C codes with emacs as well as doing compiling and running under emacs altogether. But the build-in emacs debugger is gdb, which is very similar to dbx (which I use a lot), however, I like to use dbx within emacs instead of gdb since I remember all the commands for it. Is there anyway to link dbx as the debugger instead of gdb?

  8. #8
    .........
    Join Date
    Nov 2002
    Posts
    303
    Would you call these pointer numbers integer or something else? What is a proper way to display them?
    If you have char *pointer, you could call it a pointer of type char, same with int etc. You can display a pointer like this.
    Code:
    int *pointer;
    int number;
    
    pointer = &number;
    number = 7;
    /*display the value stored in the memory address of number*/
    printf("%d", *pointer);
    
    /* Display the address of number*/
    printf("%d", pointer);
    
    /* Display the actual address of *pointer */
    printf("%d", &pointer);
    Just remember that whenever you say *pointer you are accessing the valued stored in the address that pointer points to, and whenever you say pointer you are accessing the actual address pointer points to. And finally when you say &pointer you are accessing the actual pointers address. Hope that helps goodluck.

  9. #9
    Registered User
    Join Date
    Apr 2003
    Posts
    18
    Is there any good reason to do address arithmatics instead of pointer arithmatics? Or is it always preferable to do pointer arithmatics?

    What is the bit length a unique memory address occupies -- one byte? Then a 32-bit integer will be represented by 4 memory addresses? If an integer pointer ptr points to this integer variable, will ptr have the address of the first byte of this integer number (assuming one byte is one memory address)?

    The reason I'm converting a 32-bit code to 64-bit is to use more memory. The current code (compiled for 32-bit system) can only use up to 2 gb of memory. I've been thinking that since a 64-bit pointer has 2^64 possible bit patterns --> contain 2^64 distinct memory addresses, which means along with malloc, 2^64 (bytes)can be allocated (assuming one address for every byte)?

  10. #10
    eh ya hoser, got a beer? stumon's Avatar
    Join Date
    Feb 2003
    Posts
    323
    Just to add in, pointers are unsigned integers. No matter what they point to. You can actually print the pointer out using the conversion specifier %p.%p in c is used to print addresses.
    Code:
    int a = 1;
    int *b;
    b = &a;
    printf("This is the address the pointer points to: %p", b);
    printf("This is what the pointer points to: %d, or %d", *b, a);
    Dont know if that answers any questions, or helps, but i figured i might add it in.
    Last edited by stumon; 04-04-2003 at 10:24 AM.
    The keyboard is the standard device used to cause computer errors!

  11. #11
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Originally posted by ylzhang
    What is the bit length a unique memory address occupies -- one byte?
    All pointers have the same size, no matter what they point to. The size of a pointer will be the size of the address bus - on a 32bit machines, this is 32bits or 4 bytes - on a 64bit machines, this is 64bits or 8bytes. Consider the following code:
    Code:
        printf ("%d\n",sizeof(char*));
        printf ("%d\n",sizeof(int*));
        printf ("%d\n",sizeof(long*));
        printf ("%d\n",sizeof(float*));
        printf ("%d\n",sizeof(double*));
        printf ("%d\n",sizeof(void*));
    These are all 4 on my 32bit system.
    Originally posted by stumon
    Just to add in, pointers are unsigned integers.
    To be more precise, a pointer is of integral type (ie. a whole number), the size of which depends on the width of your address bus. The size of an "unsigned integer" on a 64bit machine is 4bytes, the size of a pointer is 8 bytes.

    So, a pointer is the same no matter what it points to. The type that the pointer points to determines how many bytes are accessed when the pointer is dereferenced. For example, when you dereference a "char*", 1 byte is accessed at the memory address in the pointer. When you dereference a "int*", 4 bytes are accessed at the memory address in the pointer.

    Originally posted by ylzhang
    The reason I'm converting a 32-bit code to 64-bit is to use more memory. The current code (compiled for 32-bit system) can only use up to 2 gb of memory.
    A 32-bit system can potentially address up to 4gig (2^32 bytes) of memory. A 64-bit system can address up to 2^64 bytes of memory.

    Here is a tutorial on pointers.

    gg
    Last edited by Codeplug; 04-04-2003 at 11:03 AM.

  12. #12
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Originally posted by Codeplug
    NULL isn't defined as 0 on some systems (although I've never seen it and it may not be true anymore) - so its a good habit to always campare with NULL instead of 0 (for portability).
    You might want to take another look at Q5.10. And Q5.5, Q5.2, Q5.3, and Q5.9.
    Originally posted by Codeplug
    but I do know that a word is 2 bytes
    Maybe. I don't think of word as a fixed size. The same goes for byte (as opposed to octet).

    Originally posted by Codeplug
    All pointers have the same size, no matter what they point to. The size of a pointer will be the size of the address bus - on a 32bit machines, this is 32bits or 4 bytes - on a 64bit machines, this is 64bits or 8bytes.

    These are all 4 on my 32bit system.

    To be more precise, a pointer is of integral type (ie. a whole number), the size of which depends on the width of your address bus. The size of an "unsigned integer" on a 64bit machine is 4bytes, the size of a pointer is 8 bytes.

    So, a pointer is the same no matter what it points to.
    More vaxocentrism.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  13. #13
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    My bad....pointers are the same size on all machines except the PDP-11. Don't want to misinform any PDP-11 users out there.
    There are 64 bit compilers that can support multiple pointer sizes in the same app through pragma's which say: "all pointers from here on out are now 32bits".

    A word is 2 bytes, unless you are a literature professor.
    If you are a programmer:
    byte = 8 bits
    word = 2 bytes
    double word = 4 bytes
    quad word = 8 bytes

    As for NULL - thanks, I hate being ignorant (and showing it, doh!). I blame Motorola's C coding standards for forcing me to always compare with NULL (supposedly for the reasons I stated earlier - perhaps this convention is as old as the PDP-11).

    gg

  14. #14
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    My bad....pointers are the same size on all machines except the PDP-11. Don't want to misinform any PDP-11 users out there.
    I can think of a few others, but it's nice to see you missed the point.
    If you are a programmer:
    byte = 8 bits
    If you are a C programmer, this is not necessarily true.
    As for NULL - thanks, I hate being ignorant (and showing it, doh!). I blame Motorola's C coding standards for forcing me to always compare with NULL (supposedly for the reasons I stated earlier - perhaps this convention is as old as the PDP-11).
    I never said to use, or not to use, one or the other. To me, it sounded like you answered the question with regard to how NULL is defined:
    NULL isn't defined as 0 on some systems
    If you followed the first link, it stated the following.
    Question 5.10
    But wouldn't it be better to use NULL (rather than 0), in case the value of NULL changes, perhaps on a machine with nonzero internal null pointers?
    --------------------------------------------------------------------------------
    No. (Using NULL may be preferable, but not for this reason.) Although symbolic constants are often used in place of numbers because the numbers might change, this is not the reason that NULL is used in place of 0. Once again, the language guarantees that source-code 0's (in pointer contexts) generate null pointers. NULL is used only as a stylistic convention.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  15. #15
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    I can think of a few others...
    Oh really? What are they? I'd love to hear of a machine with a ANSI C compiler that generates code where not all pointers are the same size.

    If you are a C programmer, this is not necessarily true.
    I would love to hear your explanation on why a byte isn't necessarily 8 bits to a C programmer? Don't confuse "char" and "byte" - the size of a char is technically platform dependant - "byte" is a programming language agnostic term which means 8 bits. Even if you are confusing the two, most C programmers consider a char as a byte.

    I never said to use, or not to use, one or the other.
    I never said you did. The fact that I said "NULL isn't defined as 0 on some systems" was the ignorance I was refering to.

    gg

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 11:22 AM
  2. Replies: 12
    Last Post: 06-24-2005, 04:27 PM
  3. malloc and realloc
    By odysseus.lost in forum C Programming
    Replies: 3
    Last Post: 05-27-2005, 08:44 AM
  4. freeing problem with concurrent processes
    By alavardi in forum C Programming
    Replies: 2
    Last Post: 03-07-2005, 01:09 PM
  5. half ADT (nested struct) problem...
    By CyC|OpS in forum C Programming
    Replies: 1
    Last Post: 10-26-2002, 08:37 AM