理解C语言中的双空位指针

理解C语言中的双空位指针,c,C,我试图做一些基本的例子来理解void指针是如何工作的。下面是我编写的一个示例,它拥有一个void*字符串,并将其转换为“工作”类型,然后打印它的某些方面: int main(int argc, char *argv[]) { // Create a void pointer which "acts like" a string void * string = "hello"; // "Cast" the string so it's easier to work wi

我试图做一些基本的例子来理解void指针是如何工作的。下面是我编写的一个示例,它拥有一个
void*
字符串,并将其转换为“工作”类型,然后打印它的某些方面:

int main(int argc, char *argv[]) {

    // Create a void pointer which "acts like" a string
    void * string = "hello";

    // "Cast" the string so it's easier to work with
    char * string_cast = (char*) string;

    // Print the string and a character in it
    printf("The string is: %s\n", string_cast);
    printf("The third character is: %c\n", string_cast[2]);

    // How to now do something like:
    // (1) void pointer_to_string_obj = ?
    // (2) cast that pointer_to_string_obj to a normal string
    // (3) print the string like it would normally be done


}

有人能举例说明手动创建
*(char**)
类型的字符串指针,以及为什么首先需要创建该类型(为什么不只是普通的
char*
?)。如果我的问题很宽泛,我很抱歉,但基本上我正在尝试找出各种空指针类型以及我现在的初学者理解,这有点混乱,因此看到一些示例将非常有帮助。

因此我想出了一个双空指针的好例子(即,
void**
)。减少双重释放bug的一种方法是在释放它们之后总是将指针设置为NULL

我们可以这样做(有问题的风格):

myprojectinclude.h:

/* must happen after any standard headers */
void freep(void **pointer);
#define free(p) error_call_freep_instead p /* so that free doesn't exist anymore */
自由党:

#include <stdlib.h>
#include "myprojectinclude.h"

#undef free
void freep(void **p)
{
    if (p) {
        free(*p);
        *p = NULL;
    }
}

没有问题,因为在第一次调用后,
缓冲区
为空。(请注意,将NULL传递给free是安全的;否则我们会像几十年前那样添加NULL检查。)

你知道不是
void
的双指针吗?@Joshua当时我见过并简要使用过它们,但是不,我不能说我对单指针/数组之外的任何东西都感到满意。这里有一个双指针使用得很好的例子;但双空指针是另一回事。不要试图用
void*
来理解C中的指针,因为
void*
禁止用指针直接进行算术运算,而这是理解C指针所必需的。最好使用不同的指向指针。但是双指针很好,可以使用
void**
,因为指向的东西确实是一个指针(但尝试使用双指针理解指针也不是学习的好方法),最好使用指向
int
的指针。这种用法在技术上是无效的,尽管它经常起作用:它访问
缓冲区,类型为
char*
,通过类型为
void*
的左值,这些类型不兼容。类型
void**
不能用作“指向任何指针的指针”类型;它只能指向一个实际的
void*
@aschepler:还有没有剩余的
char*
int*
大小不同的平台?我不知道。(你如何定义“左”?)但要编写便携代码,你会考虑“所有的平台”还是一个标准?@阿切福:标准的麻烦是有这么多可供选择的。POSIX.1认为这是可行的,因为它规定所有指针的大小都是相同的。仅仅大小是不够的。它是否也指定指针使用相同的值表示形式?这并不重要——我们显然对可移植代码的含义有不同的看法。
#include <stdio.h>
#include <stdlib.h>
#include "myprojectinclude.h"

int main()
{
     char *buffer = malloc(2048);
     size_t buffer_size = 2048;

     /* ... lots of code involving reading lines, etc. */

     freep(&buffer);

     /* buffer is guaranteed to be NULL here */
}
     freep(&buffer);
     freep(&buffer);