0

I have to initialize a string array consisting only of a NULL pointer, nothing else. If I understand correctly assigning a NULL pointer looks like this:

char **array = NULL;

Otherwise, I tried

char *array[] = {NULL};

But the space for the NULL pointer should be dynamically allocated and here I'm confused, my code doesn't work.

char **array = (char**)malloc(sizeof(char*));

I would be really grateful if you could help me with this.

caddy-caddy
  • 205
  • 1
  • 5
  • 11
  • 2
    There is a difference if the pointer **is** `null` or points to a (memory location containing) `null`. Which one do you want? – DrKoch Apr 13 '15 at 14:52
  • 2
    @BLUEPIXY No, `calloc()` can't portably do this. Also, [don't cast the return value of `malloc()` and friends](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) in C. – unwind Apr 13 '15 at 14:56
  • The pointer should be null. – caddy-caddy Apr 13 '15 at 14:57

3 Answers3

5
  • char **array = NULL; is not an array, it is a pointer-to-pointer. For some reason this is a common misunderstanding. There is no relation between a pointer-to-pointer and arrays. In particular, a pointer-to-pointer is not a 2D array.

  • char *array[] = {NULL}; this is an array of pointers with 1 array items.

  • char **array = (char**)malloc(sizeof(char*)); This is very common but bad practice. Do not use this method, you'll create a fragmented look-up table splattered all over the heap.

You should use this method to allocate a true multi-dimensional array on the heap. Once you have done that, you can memset() the whole array to zero, if NULL is implemented as zero on your system (in the odd case where it isn't, you'll have to set every item of the array manually through a loop instead).

As a side note, Do I cast the result of malloc?

Community
  • 1
  • 1
Lundin
  • 195,001
  • 40
  • 254
  • 396
5

This should do it:

char **array = malloc(1 * sizeof *array);
array[0] = NULL;

This assumes the allocation succeeds, you should test that before relying on it in actual code. The 1 means "array of 1 element", it's of course redundant but I felt it added some clarity.

The above declares a pointer to (an array of) character pointers, and tries to allocate room for 1 such character pointer.

Actually doing this seems very pointless, but I can't read your mind to figure out what you probably should be doing. :)

unwind
  • 391,730
  • 64
  • 469
  • 606
  • what is the '1' for in the malloc size parameter? it seems to be totally unneeded and is similar to the often seen code that uses 'sizeof(char)' as part of the malloc size parameter. – user3629249 Apr 13 '15 at 15:52
  • 1
    @user3629249 Of course multiplying by 1 is never needed, I included it for clarity and to show how I thought. It's the size (in elements) of the array we're allocating room for. I edited. – unwind Apr 13 '15 at 15:57
  • well, `sizeof(char)` is nonsense in the vast majority of compilers, but `sizeof(wchar_t)` not. One must ask, What's the meaning of having a neutral element in a mathematical set if it doesn't affect the result of its operations? At least, you will make your code more portable, as it will compile on archs where `sizeof(char)` happens to be `!= 1`. A C manual from IBM described the use of constants in programs using an example based on `MATH_PI` (and claimed for the easyness of changing the value of the constant, case of `MATH_PI` would change in the future) – Luis Colorado Apr 14 '15 at 05:13
  • @LuisColorado `sizeof (char)` is 1 in all compliant C compilers. And all of that is totally besides the point, this is allocating one *character pointer*, not one character. – unwind Apr 14 '15 at 07:27
  • @unwind, well, my response was not for you, it was for @user3629249, who talked about `sizeof(char)` in his. But being 1 in all compliant C compilers doesn't mean a compliant compiler could not exists where `sizeof (char)` is not one. Don't flame me for that, my comment wasn't addressed to you. Normally, using `1 *` in an expression makes the code more readable, and I agree with your answer. I have even upvoted it. – Luis Colorado Apr 14 '15 at 08:11
  • @LuisColorado That sounds like a contradiction to me. :) The standard says that `sizeof (char)` is 1, so any standards-compliant compiler has to respect that. :) I suspected you didn't address me, but I'm against confusion so I had to do something. – unwind Apr 14 '15 at 08:18
  • ... but it doesn't say it's a requirement of compliance. Think logically, and suppose a machine that cannot allocate a `char` with less than, let's say, 36bit. Cannot we write a compliant compiler for it? Of course, the standard also doesn't get into the number of bits of a char, the number of bits of an `int` or the number of bits of a byte. – Luis Colorado Apr 14 '15 at 08:22
  • C11 draft 6.5.3.4: "When `sizeof` is applied to an operand that has type `char`, `unsigned char`, or `signed char`, (or a qualified version thereof) the result is 1." – unwind Apr 14 '15 at 08:26
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/75176/discussion-between-luis-colorado-and-unwind). – Luis Colorado Apr 14 '15 at 08:26
0

A NULL pointer will always have the size of a pointer. You can't change the size of a pointer.

The first two methods you tried are both ok. You're creating a variable of type char ** and then assigning it the value NULL. You can't change the size of that variable.

Mateo Hrastnik
  • 533
  • 1
  • 7
  • 20