【问题标题】:memset operation on double pointer双指针上的 memset 操作
【发布时间】:2016-12-16 10:01:10
【问题描述】:

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 执行有效操作?

【问题讨论】:

    标签: c pointers memset pointer-to-pointer


    【解决方案1】:

    在您的代码中,

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

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

    相关,引用 C11,第 7.19 章

    NULL
    它扩展为实现定义的空指针常量; [...]

    以及,第 §6.3.2.3 章

    值为 0 的整数常量表达式,或这样的表达式强制转换为类型 void *,称为null pointer constant

    因此,NULL 是指针类型,无论如何都与 int 不兼容。

    【讨论】:

    • #define NULL 0 in stddef.h
    • @overexchange 在第 7.19 章,C11 中向我展示了相同的内容。
    • NULL 只需要具有零值。但是,它可以有一个指针类型,在这种情况下,将它传递到预期 int 的位置是无效的(并且不会编译)。
    • 我期待 50(INITIAL_LIST_SIZE) 使用 memset 指向零的指针。你确定吗?如果是,那在内部是如何运作的?
    • @overexchange 抱歉,确认一下,究竟是什么?首先,不要使用0 将值设置为指针类型,因为字面量0 具有整数类型。使用NULL,这是一种更可靠、更正确的指针初始化方式。
    【解决方案2】:

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

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


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

    【讨论】:

    • 为了便于阅读,我保留了NULL,说**array 中的每个void * 都是NULL
    • @overexchange 这可能会导致编译器发出关于从指针类型转换为非指针类型的警告,具体取决于NULL 的定义。
    • 你能列举 NULL != 0 的任何情况吗?据我了解,标准没有定义 NULL,但 NULL == 0 是如此普遍,以至于它也可能如此。
    • @doron NULL 在 C 标准中定义为编译器特定的空指针常量。它在 C11 标准 (INCITS+ISO+IEC+9899-2011[2012]) 的 7.19(通用定义 )第 3 节中指定
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    相关资源
    最近更新 更多