0

I just wondered what is the proper C syntax in WHAT_GOES_HERE? below? I tried a number of things and it doesn't compile.

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define MAX_SZ 256
typedef char Name[MAX_SZ];

int main(int argc, char **argv) {
    Name *a = (Name *)malloc(10 * sizeof(Name));
    char *b[MAX_SZ] = (WHAT_GOES_HERE?)malloc(10 * sizeof(char[MAX_SZ]));
    printf("sizeof(%s) = %Zu\n", "a[3]", sizeof(a[3])); 
    // outputs "sizeof(a[3]) = 256"
    return 0;
}
8
  • 1
    Nothing: stackoverflow.com/questions/605845/… Commented Nov 17, 2018 at 0:58
  • Hmm! Has the opinion changed since K&R? On p. 167 they state: "The pointer returned by malloc or calloc has the proper alignment for the object in question, but it must be cast into the appropriate type, as in "int *ip; ip = (int *) calloc(n, sizeof(int));" Commented Nov 17, 2018 at 1:04
  • when calling any of the heap allocation functions: malloc calloc realloc, 1) always check (!=NULL) the returned value to assure the operation was successful. 2) the returned type, in C, is void* which can be assigned to any pointer. Casting just clutters the code, making it more difficult to understand, debug, etc. Commented Nov 17, 2018 at 1:23
  • regarding: typedef char Name[MAX_SZ]; and related statements: this is giving the keyword char a new meaning of Name[ MAX_SZ ] This 'can' be done' but is a very poor programming practice Commented Nov 17, 2018 at 1:24
  • 1
    @HenryBigelow: Yes, to some extent opinion has changed — see Should I cast the return value from malloc(). I side with answers such as this or this, but I learned C before void was a keyword and on a machine where the char * to a memory location was a different value from an 'anything else pointer' to the same location so the cast was crucial to getting the code to work at all (on anything other than strings). Commented Nov 17, 2018 at 1:54

1 Answer 1

2

You ask 'what goes here' in:

char *b[MAX_SZ] = (WHAT_GOES_HERE?)malloc(10 * sizeof(char[MAX_SZ]));

You want a dynamically allocated pointer to an array of 10 fixed size arrays (of char).

The first problem is "what goes on the LHS of the = sign", because what you've defined is that b is an array of MAX_SZ pointers to char, which is not what you said you wanted.

So, you need:

char (*b)[MAX_SZ] = malloc(10 * sizeof(char[MAX_SZ]));

Now you can refer to b[0] through b[9] as arrays of MAX_SZ characters.

If you want to add a cast (but see the notes and links in my comment), you need to match the type on the left-hand side minus the variable name:

char (*b)[MAX_SZ] = (char (*)[MAX_SZ])malloc(10 * sizeof(char[MAX_SZ]));

I wouldn't post such contorted code without a test, so I created a simple one based on yours and the information above, and ran it under Valgrind and got a clean bill of health.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

enum { MAX_SZ = 256 };

int main(void)
{
    /* Pass 1 */
    {
    char (*b)[MAX_SZ] = malloc(10 * sizeof(char[MAX_SZ]));
    strcpy(b[0], "The zeroth");
    strcpy(b[9], "The ninth and final element of the array");
    printf("From '%s' to '%s', all is well\n", b[0], b[9]);
    free(b);
    }

    /* Pass 2 */
    {
    char (*b)[MAX_SZ] = (char (*)[MAX_SZ])malloc(10 * sizeof(char[MAX_SZ]));
    strcpy(b[0], "The zeroth");
    strcpy(b[9], "The ninth and final element of the array");
    printf("From '%s' to '%s', all is well\n", b[0], b[9]);
    free(b);
    }

    return 0;
}

The output is boring (sorry):

From 'The zeroth' to 'The ninth and final element of the array', all is well
From 'The zeroth' to 'The ninth and final element of the array', all is well
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.