【发布时间】:2022-01-19 23:45:35
【问题描述】:
所以我有这段代码,目标是有一个void *data 指针,它有时用于存储一个简单的int,有时是一个char 数组,有时我需要存储一个char 数组的数组。
我确保我始终知道我存储在 void 指针中的数据类型。
代码在在线解析器中执行良好,这是它的输出:
sizeof 2 x char*: 8 str0: string1 addr: 2995278544 str1: bla2 addr: 2995278576 checking strings: str0: string1 addr: 2995278544 str1: bla2 addr: 2995278576
计划是为 n 个 char* 指针分配空间并将该指针保存为 void *data。然后将类型更改为“char **ptr”(指向指针的指针),这样我就可以将 strdup 返回的地址保存到该数组并稍后访问它们。 checkItems(uint8_t) 正是这样做的,它通过再次将其更改为“char **ptr”来重新访问“void *data”指针,以便能够访问保存实际 C 字符串的内存地址。
这一切都正确吗?有人会这样做吗?我应该对 void *data 指针使用某种类型的转换,而不是简单地说“char **ptr = data;”吗?
谢谢!
#include<stdio.h>
#include<stdint.h>
#include<string.h>
#include<stdlib.h>
#include<stdarg.h>
void copyItems(uint8_t num, ...);
void checkItems(uint8_t num);
void *data;
int main()
{
copyItems(2, "string1", "bla2");
checkItems(2);
}
void copyItems(uint8_t num, ...)
{
printf("sizeof %u x char*: %u\r\n", num, sizeof(char*), sizeof(char*)*num);
data = malloc(sizeof(char*)*num);
char **ptr = data;
va_list ap;
va_start(ap, num);
for (uint8_t n = 0; n < num; n++)
{
ptr[n] = strdup(va_arg(ap, char*));
printf("str%u: %s addr: %u\r\n", n, ptr[n], ptr[n]);
}
va_end(ap);
}
void checkItems(uint8_t num)
{
char **ptr = data;
printf("checking strings:\r\n");
for (uint8_t n = 0; n < num; n++)
{
printf("str%u: %s addr: %u\r\n", n, ptr[n], ptr[n]);
}
}
【问题讨论】:
-
“我确保我始终知道我存储在 void 指针中的数据类型。” 在哪里?我本来希望该信息与指针一起包含在
struct中,和存储的项目数。 -
是的,实际上 void 指针包含在存储所有信息(当然包括项目数)的结构中。因为我对此没有任何问题,所以我想让示例尽可能简单。
-
您不应该(需要)强制转换 void 指针,请参阅Do I cast the result of malloc?
-
我想我也可以说 ((char**)data)[n] 而不是创建 char **ptr。问题仍然存在,无论这是允许的,正确的和良好的做法,还是纯粹的 BS...
-
如果您要取消引用
void*指针,那么您必须强制转换它。对于分配给另一个指针类型,没有。