Boh*_* LI 0 c return function void-pointers
我有以下c代码:
#include <stdio.h>
#include <stdlib.h>
void *func(int a) {
if (a==3) {
int a_int = 5;
int *ptr_int = &a_int;
return (void *)ptr_int;
}
else if (a==4) {
char a_char = 'b';
char *ptr_char = &a_char;
return (void *)ptr_char;
}
else {
fprintf(stderr, "return value is NULL");
return NULL;
}
}
int main (int argc, char *argv[]) {
int *ptr_int = (int *)func(3);
char *ptr_char = (char *)func(4);
fprintf(stdout, "int value = %d\n", *ptr_int);
fprintf(stdout, "char value = %c\n", *ptr_char);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是当我使用gcc来测试这段代码时,我得到以下结果:
Run Code Online (Sandbox Code Playgroud)int value = 98 char value = ? root@coupure:/home/bohao/Desktop/test1375# gcc test.c -o test root@coupure:/home/bohao/Desktop/test1375# ./test int value = 98 char value = root@coupure:/home/bohao/Desktop/test1375# gcc test.c -o test root@coupure:/home/bohao/Desktop/test1375# ./test int value = 98 char value = root@coupure:/home/bohao/Desktop/test1375# gcc test.c -o test root@coupure:/home/bohao/Desktop/test1375# ./test int value = 98 char value = root@coupure:/home/bohao/Desktop/test1375# gcc test.c -o test root@coupure:/home/bohao/Desktop/test1375# ./test int value = 98 char value = root@coupure:/home/bohao/Desktop/test1375# gcc test.c -o test root@coupure:/home/bohao/Desktop/test1375# ./test int value = 98 char value = g root@coupure:/home/bohao/Desktop/test1375# gcc test.c -o test root@coupure:/home/bohao/Desktop/test1375# ./test int value = 98 char value = root@coupure:/home/bohao/Desktop/test1375# gcc test.c -o test root@coupure:/home/bohao/Desktop/test1375# ./test int value = 98 char value = !
为什么我有ptr_int 的98和ptr_char的随机值?
我想要的是拥有一个可以返回不同类型的值而不是使用两个函数的通用函数.那可能吗 ?如果是这样,怎么办?
我看到的问题是,你正在尝试return
从函数(范围)中获取局部变量的地址,并尝试从调用者访问返回的内存.在调用者中,内存无效,任何使用都将导致 未定义的行为.
解决方案:您需要为要从函数中指定的指针(malloc()
/ calloc()
)使用动态内存分配return
.这将解决这里的问题,因为动态分配的内存的生命周期是free()
手动或直到程序终止,以较早者为准.
话虽如此,这种方法并不是一个好方法.如果要返回多种类型中的一种,请转到struct
所有类型的包含成员,并使用标记来标记类型.填充相应的成员变量,设置标志和return
结构变量.
为了更好,您实际上可以使用an union
作为结构的成员,因为您一次只需要一种类型.对于工作代码,请参考对方的回答通过@pmg.
您可以返回(包含结构体)一个联合
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
union members {
int *intp;
char *charp;
double doublev;
};
struct group {
int lastunionmember;
union members x;
};
struct group f1(void) {
struct group r = {0};
int choice = rand() % 3;
if (choice == 0) {
r.x.intp = malloc(sizeof (int)); // remember to free(intp) at some time
*r.x.intp = 42;
r.lastunionmember = 1;
}
if (choice == 1) {
r.x.charp = malloc(42); // remember to free(charp) at some time
strcpy(r.x.charp, "forty two");
r.lastunionmember = 2;
}
if (choice == 2) {
r.x.doublev = 3.14159;
r.lastunionmember = 3;
}
return r;
}
int main(void) {
struct group x;
srand(time(0));
for (int k = 0; k < 20; k++) {
x = f1();
switch (x.lastunionmember) {
default: printf("invalid value\n"); break;
case 1: printf("int value is %d\n", *x.x.intp); break;
case 2: printf("string is \"%s\"\n", x.x.charp); break;
case 3: printf("double value is %f\n", x.x.doublev); break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
查看在 ideone 上运行的代码。