Thread: Okay to use sizeof(void*) when allocating a new pointer to a string?

  1. #1
    Registered User
    Join Date
    Jun 2009
    Posts
    101

    Okay to use sizeof(void*) when allocating a new pointer to a string?

    I have a pointer-pointer variable that contains strings of characters. It is dynamically added to when more data becomes available. I must first allocate the pointer to each string, and then allocate the actual string:

    Code:
    char **phrases = NULL;
    
    char temp[] = "Hi there!";
    
    phrases = malloc(sizeof(*phrases));
    phrases[0] = malloc(sizeof(temp)+1);
    strcpy(phrases[0],temp);
    The thing is, since I know the pointer to the string will always be 4 or 8 (depending on the machine architecture), can't I just use sizeof(void*)? sizeof(void*) should return 4 or 8, depending on whether I compiled 32 or 64 bit.

  2. #2
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    As per line 5, you clearly know the best way to do it, so why would you ask about any not-as-good way of doing it?
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  3. #3
    Registered User
    Join Date
    Jun 2009
    Posts
    101
    Quote Originally Posted by iMalc View Post
    As per line 5, you clearly know the best way to do it, so why would you ask about any not-as-good way of doing it?
    Well, the question wasn't really about which way is "better" or not. I'm more concerned about whether there will be any problems doing it the other way, that is using a generic void*.

    Why do you think using void* isn't as good? Not trying to be combative, just genuinely curious.

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Quote Originally Posted by synthetix View Post
    Why do you think using void* isn't as good? Not trying to be combative, just genuinely curious.
    Pointers don't have to be the same size, even though data pointers are usually 4 bytes wide today. Most if not all of the things that you allocate will be data-related, but still. Ever hear the phrase, assumptions make an ass out of you and me? That's basically what's going on here.

    For the final authority, nothing better than the standard, though.
    Quote Originally Posted by 6.2.5.27
    A pointer to void shall have the same representation and alignment requirements as a pointer to a character type. Similarly, pointers to qualified or unqualified versions of compatible types shall have the same representation and alignment requirements.28) All pointers to structure types shall have the same representation and alignment requirements as each other. All pointers to union types shall have the same representation and alignment requirements as each other. Pointers to other types need not have the same representation or alignment requirements.
    Last edited by whiteflags; 07-19-2012 at 04:29 PM.

  5. #5
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by synthetix View Post
    Well, the question wasn't really about which way is "better" or not. I'm more concerned about whether there will be any problems doing it the other way, that is using a generic void*.
    It's not impossible that doing it "the other way" could cause problems, but as you already know how to do what will always work, there's probably no point in asking.
    If you're really "just curious" then track down and read a copy of the standard.
    If there's the slightest hint that you might consider writing code that way then that would be a waste.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Well, the standard does not guarantee that a void * is the same size as a char * (having the "same representation and alignment requirements" as per the clause whiteflags quoted doesn't necessarily mean "identical representation"). In practice, since any pointer must survive a round-trip conversion (X * -> void * and back) a sizeof(void *) will normally be at least the size of any other pointer. That doesn't exclude a void * being larger than another pointer type. Which makes allocating a memory for a void * when you actually need memory for a char * unnecessarily wasteful - it may allocate more memory than needed.

    That said, I have yet to come across any report or documentation of a compiler that supports a void * that is of different size than a char *. There is also no guarantee that pointers have any particular sizes.

    In the end, however, I agree with iMalc's point. Code is easier to understand, and therefore easier to get right, if it explicitly does what is intended. In this case, you intend to allocate a char *. Using malloc(sizeof(void *)) may do nothing different, technically. But in your code, it obfuscates the meaning without any benefit. Code with obfuscated meaning is code that can trick a programmer (including yourself at some future date) into believing the code does something different than it actually does, and therefore introduce subtle bugs.

    Incidentally, your code (even without changing it to work with allocate sizeof(void *)) has two potentially serious bugs.

    Firstly, it does not check that phrases is non-NULL before allocating memory to phrases[0]. It should.

    Second, the allocation of phrases[0] = malloc(sizeof(temp)+1); is flawed in several ways. sizeof(temp) will be the length of temp + 1 (i.e. sizeof(temp) catches the terminating zero byte in temp). Your code is therefore allocating more memory than needed. Your code will also break miserably if the code is ever restructured so temp is a pointer. For example, if your code is changed to this
    Code:
    char **phrases = NULL;
     
    char *temp = "Hi there!";
     
    phrases = malloc(sizeof(*phrases));
    phrases[0] = malloc(sizeof(temp)+1);    /*   Should check that phrases is non-NULL first */
    strcpy(phrases[0],temp);
    Then sizeof(temp) will be the size of a pointer to char, not the size of the string. If sizeof(temp) < strlen(temp) ever occur, which it can and probably will, then the strcpy() call yields undefined behaviour.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    Registered User
    Join Date
    Jun 2009
    Posts
    101
    Quote Originally Posted by grumpy View Post
    Using malloc(sizeof(void *)) may do nothing different, technically. But in your code, it obfuscates the meaning without any benefit. Code with obfuscated meaning is code that can trick a programmer (including yourself at some future date) into believing the code does something different than it actually does, and therefore introduce subtle bugs.
    Thanks. That's a valid point and I certainly agree.

    Firstly, it does not check that phrases is non-NULL before allocating memory to phrases[0]. It should.
    Ah. Good call. I will definitely do that.

    Second, the allocation of phrases[0] = malloc(sizeof(temp)+1); is flawed in several ways. sizeof(temp) will be the length of temp + 1 (i.e. sizeof(temp) catches the terminating zero byte in temp). Your code is therefore allocating more memory than needed.
    Actually, the code I posted was wrong. That line should have used strlen() instead of sizeof():

    Code:
    phrases[0] = malloc(strlen(temp)+1);
    The extra char was added to malloc() to account for the terminating character, which is not taken into account by strlen().

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by synthetix View Post
    Actually, the code I posted was wrong. That line should have used strlen() instead of sizeof():
    You're more-or-less confirmed my point.

    While it is a good form to keep code you post to forums small (which you did) it is really poor form to post code that differs from your actual code. Otherwise, you just waste people's time and effort.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. *void allocating
    By flegmik in forum C Programming
    Replies: 4
    Last Post: 11-23-2011, 06:35 PM
  2. void ** ?? sizeof(void*)?? what is this?
    By nacho4d in forum C Programming
    Replies: 9
    Last Post: 10-02-2009, 07:22 AM
  3. Allocating a double pointer as an array
    By sharrakor in forum C Programming
    Replies: 3
    Last Post: 04-16-2009, 07:02 AM
  4. Replies: 4
    Last Post: 08-27-2007, 11:51 PM
  5. sizeof(void *)*1
    By darksaidin in forum C++ Programming
    Replies: 25
    Last Post: 07-25-2003, 09:51 AM