如何解决C将void指针数组传递给函数
我想将一个空指针数组传递给一个函数,该函数填充它的结果与 integer
一起工作正常,但我在返回 char*
时遇到了麻烦
int function(void *arr[]);
int main(void) {
void *arr[3];
function(arr);
printf("%d\n",*(int *)&arr[0]);
printf("%d\n",*(int *)&arr[1]);
printf("%s\n",(char *)&arr[2]);
}
int function(void *arr[]){
arr[0] = (void*)(int)4;
arr[1] = (void*)(int)6;
char* test = "abc";
arr[2] = (void*)test;
return 0;
}
对于字符串我没有得到正确的值
解决方法
arr
的类型为 void(*)[3]
。
arr[0]
的类型为 void*
。它存储适当转换的 4
值这一事实无关紧要。
&arr[0]
的类型为 void**
。
(int *)&arr[0]
具有类型 int*
,但它指向类型为 void*
的对象,而不是指向类型为 int
的对象。这不是指针通常所做的。您可以拥有这样一个指针,但是您可以合法使用它的唯一事情是将其转换回正确的类型,在本例中为 void**
。你没有这样做。
*(int *)&arr[0]
的类型为 int
。
在这里,您通过 void*
类型的左值访问 int
类型的对象。这是未定义的行为。不要那样做。
如果您想将 arr[0]
转换回 int
,只需这样做:
printf("%d\n",(int)arr[0]);
同样,如果您想将 arr[2]
转换回 char*
,只需这样做:
printf("%s\n",(char*)arr[2]);
,
您可以传递一个 void
数组,并将该数组元素分配给一个动态分配的内存区域,用于存储指向的值。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int function(void *arr[]){
arr[0] = malloc(sizeof(int));
if (arr[0] == NULL) goto ERR_MALLOC_0;
*(int*)arr[0] = 4;
arr[1] = malloc(sizeof(int));
if (arr[1] == NULL) goto ERR_MALLOC_1;
*(int*)arr[1] = 6;
const char *const test = "abc";
arr[2] = malloc(strlen(test));
if (arr[2] == NULL) goto ERR_MALLOC_2;
strcpy(arr[2],test);
return 0;
// remember about error checking
free(arr[2]);
ERR_MALLOC_2:
free(arr[1]);
ERR_MALLOC_1:
free(arr[0]);
ERR_MALLOC_0:
return -1;
}
int main(void) {
void *arr[3];
int err = function(arr);
if (err == -1) abort();
// & is the address of element,not it's element
printf("%d\n",*(int*)arr[0]);
printf("%d\n",*(int*)arr[1]);
printf("%s\n",(char*)arr[2]);
// remember to free memory
for (int i = 0; i < 3; ++i) {
// funny how we do not need to know the effective type
free(arr[i]);
}
}
但是这样的功能显然是令人困惑的,并且会导致许多错误和问题。而是实际使用正确类型的变量:
#include <stdlib.h>
#include <string.h>
int function(int *val1,int *val2,char **string) {
*val1 = 3;
*val2 = 6;
const char *test = "abc";
*string = malloc(strlen(test));
if (*string == NULL) return -1;
strcpy(*string,test);
return 0;
}
int main(void) {
int val1;
int val2;
char *string;
int err = function(&val1,&val2,&string);
if (err == -1) abort();
printf("%d\n",val1);
printf("%d\n",val2);
printf("%s\n",string);
free(string);
}
如果你真的想在不同的数据类型上实现一些虚拟表示和操作,使用普通的“void
指针数组”将一事无成,因为这样的数组不知道什么是底层类型存储的值 - 作为程序员,您必须知道该数组中的内容(即 arr[0]
是 int
,arr[2]
是 char*
),如您所知,您不妨从一开始就使用正确类型的变量。
arr[0] = (void*)(int)4;
上一行将整数 4 转换为空指针(地址)并将其存储在数组 arr
中作为指针地址。我想这不是你想要的。
为了以您想要的方式使用 void 指针访问数据,首先使其指向有效的内存地址,该地址将在函数退出时保存数据。在为函数内部的空指针分配内存地址时必须小心,当函数退出时,该函数堆栈中的所有变量(局部变量)都将从堆栈中弹出,从而使该内存地址无效。如果您想在函数外使用它,则在将内存地址分配给函数内的指针时仅使用静态(或全局)或动态内存。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。