我正在尝试做一些非常基本的示例来理解 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指针的好例子(即void**
)。减少双重释放错误的一种方法是在释放指针后始终将它们设置为 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 */
freep.c:
#include <stdlib.h>
#include "myprojectinclude.h"
#undef free
void freep(void **p)
{
if (p) {
free(*p);
*p = NULL;
}
}
main.c:
#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);
没有任何问题,因为第一次调用后 buffer
为 NULL。 (请注意,将 NULL 传递给 free 是安全的;否则我们将像几十年前那样添加 NULL 检查。)
评论中关于可移植性争论的总结:此代码假设所有数据指针具有相同的大小和表示形式(大多数情况下,旧的 36 位平台具有相同的大小和 int* 和 char* 的不同位布局,对于 NULL 看起来相同)两个都)。过去存在的平台并非如此。此代码适用于 Unix、DOS、Windows 和大多数其他操作系统。
关于c - 理解 C 中的双空指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58045351/