好的,这是针对学校项目的,但我的问题与具体实现无关,我也没有寻求有关项目本身的任何帮助。我之所以发出此警告,是因为我想为我正在做的事情提供上下文,但这是一个关于 void 指针转换的一般性问题,在项目的上下文中构建......我正在编写的这个函数不是'即使对于项目而言,它也只是我作为测试机制编写的东西,以查看我生成的数据结构是否正常工作……它导致我遇到涉及 printf()、格式说明符和转换的问题……我基本上必须实现一个链表(称为“队列”,但根本不是真正的队列),并且我编写了一个函数来测试它。
基本上有一个名为“Chunk”的结构,带有一些变量(first 是较大数组中的索引,它是给定“Chunk”的第一个元素,arr 基本上是 larger_array[c->first],但它实际上是一个空指针:void *arr,其中 c 是一个指向 block 的指针),它指示更大数组中的位置。所以基本上如果你有一个像 a = {5,7,3,4,6,9,1,2} 这样的数组,并且给定的 block 大小为 2,那么你有 4 个 block ,每个 block 都有一个“arr”分别指向5、3、6、1的void指针变量。
无论如何,我写了一个“print_queue”函数(实际上是一个 block 链表),耶!它根据需要打印所有信息,这是我将分享的核心部分:
while (index < num_chunks) {
first = c->first;
printf("Chunk %d: first is %d and a[%d] is ", index, first, first);
if (elem_size == LONG_SIZE) /* LONG_SIZE defined above as 8 */
printf("%ld\n", c->arr);
else if (elem_size == INT_SIZE) /* INT_SIZE defined above as 4 */
printf("%d\n", c->arr);
else if (elem_size == CHAR_SIZE) /* CHAR_SIZE defined above as 1 */
printf("%c\n", c->arr);
index++;
if (c->next != NULL)
c = c->next;
}
我基本上想编写一个函数,在实现项目的实际功能(多线程合并-种类)。所以上面的代码确实有效!这是此数组输入的输出:
char original[] = {'z', 'y', 'x', 'w', 'v', 'u', 't', 's'};
输出:
Chunk 0: first is 0 and a[0] is z
Chunk 1: first is 2 and a[2] is x
Chunk 2: first is 4 and a[4] is v
Chunk 3: first is 6 and a[6] is t
原来如此!耶!但是,我收到了这些编译器警告:
mergesort.c: In function 'print_chunk_queue':
mergesort.c:85:7: warning: format '%ld' expects argument of type 'long int', but argument 2 has type 'void *' [-Wformat]
mergesort.c:87:7: warning: format '%d' expects argument of type 'int', but argument 2 has type 'void *' [-Wformat]
mergesort.c:89:7: warning: format '%c' expects argument of type 'int', but argument 2 has type 'void *' [-Wformat]
所以我所做的是将所有 c->arr 转换为 (type *) c->arr,但这给了我更多关于“哦,我们想要一个 int,但你有一个 int 指针”的警告,那又怎样我当时做的是:
* ((type *) c->arr)
基本上取消引用我类型转换的 void 指针(它永远不会为 null!它总是指向有效数字,至少在我提供的输入中是这样!),然后这给了我一个段错误!。所以我非常沮丧,因为我从带有大量“警告”的工作输出变成了无用的段错误。
编辑:
根据要求定义数据结构:
typedef struct chunk {
void *arr;
struct chunk *next;
int first;
} Chunk;
这就是我设置单个 block 的状态并创建 block 的链接列表的方式:
while (index < number_of_chunks) {
if (index == 0) {
if ((current = malloc(sizeof(Chunk))) == NULL)
err(EX_OSERR, "memory allocation has failed\n");
head = current;
}
current->first = (chunk_size * index);
current->arr = ((char *) array)[current->first];
current->size = chunk_size;
if (index != (number_of_chunks - 1)) {
if ((current->next = malloc(sizeof(Chunk))) == NULL)
err(EX_OSERR, "memory allocation has failed\n");
current = current->next;
}
else {
tail = current;
}
index += 1;
}
最佳答案
current->arr = ((char *) array)[current->first];
这里应该有一个&
。您想要将字节的地址分配给arr
,而不是它的值。
current->arr = &((char *) array)[current->first];
如果你这样做,那么 arr
将包含一个地址,这将允许转换和取消引用工作。
printf("%ld\n", *(long *) c->arr);
printf("%d\n", *(int *) c->arr);
printf("%c\n", *(char *) c->arr);
关于转换 void 指针并使用格式说明符打印,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18197685/