Thread: Pointers + Malloc = Painloc

  1. #1
    Registered User
    Join Date
    Oct 2008
    Posts
    3

    Pointers + Malloc = Painloc

    I am yet another college student trying to figure out malloc and pointers. I've spent the last 7 hours working on a rather involved project, and I'm stuck, stuck, stuck. After some fruitless googling, and forum searching, I've got a few questions that I'm hoping some of you would be willing to answer. Thanks in advance!

    What I'm trying to do:
    I need to create a "void pointer to the global memory" and allow the user to input certain commands that put data into various locations. For example: "stoint 2a3fh @4ah" stores the hexadecimal integer 2a3f in the hexadecimal address 4a. Possible data that will be put in are hexadecimal integers, and variable length strings. I also need a function that dumps the contents of the pointer in such a way that the hex value of each byte is displayed.

    Questions:
    1. Void pointers?
      my project says
      Quote Originally Posted by my evil professor
      declare a void pointer to the global memory
      initialize the pointer using malloc to allocate 256 bytes
      I thought I could do that with
      Code:
      void *mem[256] = (void *) malloc(256);
      but apparently if I put that above my main functions (where I declare all the function prototypes and whatnot) it doesn't compile.

    2. How do I access the data?
      I'm guessing that actually initializing the mem pointer is really easy to do. I'm sure that I'm close but I can't quite grasp it. What is completely baffling me though, is once I have this pointer of 256 bytes... how do I traverse it and print the data inside it? More importantly, how do I put other things inside the pointer (characters or integers)?

    3. What's %p?
      In a small c program my professor wrote, he uses %p to show some data. I can't figure out what that's supposed to mean. I thought you used %x for hex? Incidentally, I've pored over that program for hints on what to do here... still rather confused though.




    Ugh. That's a lot of stuff. If anyone is able to give me some ideas, I would really appreciate it. If I used terminology that doesn't make sense, sorry about that, I'm new to C (as you can tell). Also, if it clarifies things any, here's a sample memory dump given in the project (left column is relative memory location, middle column is hexadecimal output?, right column is any printable character):
    Code:
    stoint ch @12h  // user input
    stoint 3h @16h  // user input
    stostr "this is fun" @22h  // user input
    dump  // user input
    0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0010: 00 00 0c 00 00 00 03 00 00 00 00 00 00 00 00 00   ................
    0020: 00 00 74 68 69 73 20 69 73 20 66 75 6e 00 00 00   ..this is fun...  // LIES
    0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    00a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    00b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    00c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    00d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    00e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    00f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    %x prints an integer as hex, yes. Since you don't have an integer (you have a pointer), that's irrelevant. %p prints a pointer.

    What do you (or your professor) think "global memory" means?

  3. #3
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    I'm guessing that actually initializing the mem pointer is really easy to do. I'm sure that I'm close but I can't quite grasp it. What is completely baffling me though, is once I have this pointer of 256 bytes... how do I traverse it and print the data inside it? More importantly, how do I put other things inside the pointer (characters or integers)?
    Simple pointer arithmetic . You will have to cast however, (ie to char * or int *) as you can't do arithmetic on void pointers since the void type has no size.

    BTW,
    Code:
    void *mem[256] = (void *) malloc(256);
    Is an array of 256 void pointers... Not what you want. You need 1 void pointer that points to 256 bytes that you allocated, the cast on malloc() is also pointless (See the FAQ) -- but casting (void *) to (void *) does nothing...

    Code:
    void * mem = malloc(256);
    Last edited by zacs7; 10-18-2008 at 07:55 PM.

  4. #4
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by Chalks View Post

    Void pointers?
    my project says
    Quote Originally Posted by my evil professor
    declare a void pointer to the global memory
    initialize the pointer using malloc to allocate 256 bytes
    I thought I could do that with
    Code:
    void *mem[256] = (void *) malloc(256);
    but apparently if I put that above my main functions (where I declare all the function prototypes and whatnot) it doesn't compile.
    You declared an array of void pointers. You only want one pointer.

    [*]How do I access the data?
    I'm guessing that actually initializing the mem pointer is really easy to do. I'm sure that I'm close but I can't quite grasp it. What is completely baffling me though, is once I have this pointer of 256 bytes... how do I traverse it and print the data inside it? More importantly, how do I put other things inside the pointer (characters or integers)?
    Bytes are represented by the types "signed char" and "unsigned char", depending if you want the value to be treated as signed or unsigned. So you need a pointer to one of these types. Traversing the array requires a loop that prints out each byte. This can be done by printing each offset from your pointer with [], or by incrementing your pointer and printing out what value it points to in a loop.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  5. #5
    Registered User
    Join Date
    Oct 2008
    Posts
    3
    Thanks for the quick responses. I'm about to go to a computer lab where I can deal with this some more. I do have another clarifying question though:
    Quote Originally Posted by zacs7 View Post
    Code:
    void *mem[256] = (void *) malloc(256);
    Is an array of 256 void pointers... Not what you want. You need 1 void pointer that points to 256 bytes that you allocated, the cast on malloc() is also pointless (See the FAQ) -- but casting (void *) to (void *) does nothing...
    So should I do something like this?
    Code:
    void *mem = malloc(256);
    
    int main()
    {
      int i = 0;
      for(i=0; i<256; i++) {
        mem[i] = NULL; }  // all locations should be initialized to NULL.
    
      return 0;
    }
    Or is it more like this?

    Code:
    void *mem[256];
    
    int main()
    {
      int i = 0;
      for(i=0; i<256; i++) {
        mem[i] = malloc(1); }
    
      return 0;
    }

    I'll be attempting both of those methods in about 2 hours. *hopes to finish tonight*
    Last edited by Chalks; 10-19-2008 at 10:05 AM. Reason: clarification

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    1) Mem should be inside main.
    2) You should initialize them to NULL unless you allocate some more memory.
    3) The ending } should most likely be on its own line to help readability.
    4) You must free what you malloc. You currently are not.

    And just for the sake of it...
    T* vs T *: http://www.research.att.com/~bs/bs_faq2.html#whitespace
    If you're interested.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Ex scientia vera
    Join Date
    Sep 2007
    Posts
    477
    Quote Originally Posted by Elysia View Post
    1) Mem should be inside main.
    2) You should initialize them to NULL unless you allocate some more memory.
    3) The ending } should most likely be on its own line to help readability.
    4) You must free what you malloc. You currently are not.

    And just for the sake of it...
    T* vs T *: http://www.research.att.com/~bs/bs_faq2.html#whitespace
    If you're interested.
    There's nothing about the subject at the link you posted.

    What *is* the difference?
    "What's up, Doc?"
    "'Up' is a relative concept. It has no intrinsic value."

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by IceDane View Post
    There's nothing about the subject at the link you posted.
    What *is* the difference?
    There is a difference, in the way it's written and interpreted.
    To the compiler, it's the same.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Registered User
    Join Date
    Oct 2008
    Posts
    3
    ok, I've gotten mem properly malloced, but I don't really understand what this is pointing to. *mem is pointing to a block of memory 256 bytes long, right? How do I put something in that memory? I.E., if I want the 245th byte to hold the hex "4a", how do I do that?

    I've tried:
    Code:
      void *mem = malloc(256); // I think this is the right initialization
      mem[245] = 71;
      *mem[245] = 71;
      (&mem)[245] = (void *)71;  // gives warning without cast
      mem += 245;  // increments by 245*4 bytes.  I think?
      *mem = 71;
    none of them work, and in fact all lines (except for those with comments) above give a warning and an error:
    warning: derefrencing 'void *' pointer
    error: invalid use of void expression


    What is a valid use of a void expression?


    Edit: Elysia, I am freeing 'mem', I just didn't put it in the above code. I was typing it in a hurry.
    EDIT 2: Maybe I found my answer? Does this make sense to anyone:
    Code:
      void *mem = malloc(256);
      int i = 0;
      unsigned char *test;
      for(i=0; i<256; i++) {
        test = mem;
        if(i==0) *test = 71;
        printf("&#37;p(%p), ", (mem)++, *test);
    Last edited by Chalks; 10-19-2008 at 12:31 PM.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Since void* is a generic pointer, it means it can point to anything and the compiler doesn't know what. That's why it's undefined behavior or invalid to do stuff with it.
    But in case you want to access the 245th byte, you just want to make sure to use a type whose size is 1 byte, since that would ensure that the code is correct.
    If you allocate 256 bytes and each element takes 4 bytes, there cannot be 256 elements, as you understand.
    That's why it's common to cast it to char*, since it's guaranteed to be 1 byte.
    A pointer acts just like an array:

    Code:
    char* p = (char*)malloc(256);
    p[245 - 1] = 71;
    free(p);
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. malloc + segmentation fault
    By ch4 in forum C Programming
    Replies: 5
    Last Post: 04-07-2009, 03:46 PM
  2. Structures, arrays, pointers, malloc.
    By omnificient in forum C Programming
    Replies: 9
    Last Post: 02-29-2008, 12:05 PM
  3. malloc pointers within a struct
    By tikelele in forum C Programming
    Replies: 3
    Last Post: 11-20-2007, 11:02 AM
  4. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  5. pointers
    By fanaonc in forum C Programming
    Replies: 3
    Last Post: 11-17-2001, 02:18 AM