1

Question is relevant.

For the below representation,

  typedef struct List{

    void **array; // array of void*
    int lastItemPosition;
    int size;
  }List;

  #define INITIAL_LIST_SIZE 50

createList performs as shown below,

List *createList(List *list, Op opType){

  List *lptr = (List *)malloc(sizeof(List));

  if(opType == CREATE_NEW_LIST){

    lptr->array = malloc(INITIAL_LIST_SIZE*sizeof(void*));
    lptr->array = memset(lptr->array, NULL, INITIAL_LIST_SIZE*sizeof(void *));
    lptr->lastItemPosition = -1;
    lptr->size = INITIAL_LIST_SIZE;
}

Is memset performing valid operation on lptr->array?

Community
  • 1
  • 1
overexchange
  • 15,768
  • 30
  • 152
  • 347

2 Answers2

3

In your code,

 memset(lptr->array, NULL, INITIAL_LIST_SIZE*sizeof(void *));

is wrong, as the second argument is expected to be an int, you're passing a pointer. The conversion is a highly implementation defined behaviour, and in most of the cases, it would invoke UB.

Related, quoting C11, chapter §7.19

NULL
which expands to an implementation-defined null pointer constant; [...]

and, chapter §6.3.2.3

An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.

So, NULL is of pointer type which is not the compatible type to an int in any ways.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • `#define NULL 0` in `stddef.h` – overexchange Dec 16 '16 at 10:04
  • @overexchange show me the same in chapter 7.19, C11. – Sourav Ghosh Dec 16 '16 at 10:05
  • `NULL` is only required to have a value zero. However, it CAN have a pointer type, in which case passing it where an `int` is expected is invalid (and will not compile). – Peter Dec 16 '16 at 10:06
  • Am expecting 50(`INITIAL_LIST_SIZE`) pointers to zero using `memset`. Can you confirm? If yes, How is that working internally? – overexchange Dec 19 '16 at 17:56
  • @overexchange Sorry, confirm what, exactly? First of all, don't use `0` to set a value to a pointer type, as the literal `0`, has a type integer. Use `NULL`, which is more reliable and correct way to initialize a pointer. – Sourav Ghosh Dec 19 '16 at 18:00
  • ##1) Is this [answer](http://stackoverflow.com/a/1367411/3317808) obsolete wrt initialising zero? To initialise `NULL` to 50 pointers pointed by `lptr->array`, `memset` is not the right choice. Shall I use for-loop ? ##2) Can you confirm, whether lptr->array has set 50(INITIAL_LIST_SIZE) pointers to zero using `memset`? – overexchange Dec 19 '16 at 18:12
1

It's valid on all major platforms, except for one thing: Don't pass NULL as the value to set. Remember that the memset function operates on the individual bytes of the memory, and you should set all the bytes to zero (0).

It is however not strictly technically valid. On most major platforms a null pointer is equal to zero. But it doesn't have to be that. The only fully portable and safe way to do it is through a manual loop where you set each pointer explicitly to NULL.


And if anyone is interested to know, even if NULL is defined as 0 (or ((void *) 0)) it doesn't matter. The compiler will translate that zero into the platform-specific version of a null pointer, which may be something else than the actual integer zero.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • I kept `NULL` for readability saying that each `void *` in `**array` is `NULL` – overexchange Dec 16 '16 at 10:08
  • @overexchange That could cause the compiler to emit a warning about conversions from pointer to non-pointer type, depending on the definition of `NULL`. – Some programmer dude Dec 16 '16 at 10:09
  • Can you enumerate any case where NULL != 0? As far as I understand NULL is not defined by the standard yet NULL == 0 is so ubiquitous that it may as well be. – doron Dec 16 '16 at 11:25
  • @doron `NULL` is defined in the C standard as a compiler-specific null-pointer constant. It's specified in 7.19 (Common definitions ) section 3 of the C11 standard (INCITS+ISO+IEC+9899-2011[2012]) – Some programmer dude Dec 16 '16 at 11:58