双指针的memset操作

memset operation on double pointer

Question 相关。

对于以下表示,

  typedef struct List{

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

  #define INITIAL_LIST_SIZE 50

createList执行如下图,

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;
}

memset 是否对 lptr->array 执行有效操作?

在您的代码中,

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

是错误的,因为第二个参数应该是 int,您正在传递一个指针。转换是高度实现定义的行为,在大多数情况下,它会调用 UB。

相关,引用 C11,章节 §7.19

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

和第 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.

因此,NULL 是指针类型,在任何方面都不是 int 的兼容类型。

它在所有主要平台上都有效,除了一件事:不要将 NULL 作为要设置的值传递。请记住,memset 函数对内存的单个 字节 进行操作,您应该将所有字节设置为零 (0)。

然而,它在技术上并不严格有效。在大多数主要平台上,空指针等于零。 但是不一定是这样。唯一完全可移植且安全的方法是通过手动循环将每个指针明确设置为 NULL.


如果有人有兴趣知道,即使NULL定义为0(或((void *) 0))也没关系。编译器会将那个零翻译成平台特定版本的空指针,它可能不是实际的整数零。