C++从结构的数组中获得了错误的值

C++ got wrong value from array of struct

本文关键字:获得了 错误 数组 结构 C++      更新时间:2023-10-16

问题如上所述。当我试图从加载的*.so文件(使用libdl)中读取值时,当它们在结构中时,我得到了错误的值应用代码:

#include <dlfcn.h>
#include <iostream>
/* For face data type reproduction */
#define GET_FACE_XYZ_SIZE 1
/* For face_array reproduction */
#define GET_FACE_ARRAY_SIZE 2
#define GET_OBJECT_DATA 3
typedef struct face {
float x[1000];
float y[1000];
float z[1000];
int vertices;
} face;

int main()
{
void *hook;
int (*fn)(int request_type, void *ptr);
hook = dlopen("/root/osms/dlopen-test/lib.so", RTLD_LAZY);
if(!hook)
{
std::cout << "Couldn't find lib.so" << std::endl;
}
fn = dlsym(hook, "object_info");
int face_array_size = fn(GET_FACE_ARRAY_SIZE, NULL);
std::cout << "FACE_ARRAY_SIZE: " << face_array_size << std::endl;
face pointer[face_array_size];
fn(NULL, pointer);
dlclose(hook);
std::cout << "pointer[0].z[1]: " << pointer[0].z[1] << std::endl;
return 0;
}

和lib.so:的代码

/* For face data type reproduction */
#define GET_FACE_XYZ_SIZE 1
/* For face array reproduction */
#define GET_FACE_ARRAY_SIZE 2
#define GET_OBJECT_DATA 3
typedef struct face {
float x[1000];
float y[1000];
float z[1000];
int vertices;
} face;
extern "C" int object_info(int request, void *ptr)
{
face face_array[2];
face_array[0].x[0] = 1.1;
face_array[0].y[0] = 0.5;
face_array[0].z[0] = 1.2;
face_array[0].x[1] = 1.6;
face_array[0].y[1] = -0.11;
face_array[0].z[1] = -12;
face_array[0].x[2] = -0.12;
face_array[0].y[2] = 0.24;
face_array[0].z[2] = -0.12;
face_array[0].vertices = 3;
face_array[1].x[0] = -1.1;
face_array[1].y[0] = 0.15;
face_array[1].z[0] = -1.2;
face_array[1].x[1] = -1.6;
face_array[1].y[1] = 0.11;
face_array[1].z[1] = 1.2;
face_array[1].x[2] = 0.12;
face_array[1].y[2] = -0.24;
face_array[1].z[2] = 0.12;
face_array[1].vertices = 3;
if(request == GET_FACE_ARRAY_SIZE)
{
return 2;
}
else
{
ptr = face_array;
}
}

预期的输出是pointer[0].z[1]: -12,但我得到的是pointer[0].z[1]: -0.12。我的代码出了什么问题?

提前感谢

访问

pointer[0].z[1]

具有未定义的行为,因为它具有不确定的值。


object_info从不修改ptr所指向的数组。它只是修改一个局部数组,并将局部ptr分配给该局部数组。

解决方案:不要声明本地数组,而是修改参数所指向的数组。换句话说,将face face_array[2];重新命名为:

face* face_array = (face*)ptr;

并且去掉ptr = face_array;,它没有任何意义。


object_info被声明为返回int,但并非所有代码路径都返回值。当函数到达object_info的末尾而没有返回语句时,行为是未定义的。

解决方案:如果函数不是void,则始终返回一个值。


face_array_size不是编译时常数值,因此face pointer[face_array_size];将声明一个可变长度数组。C++中不允许使用VLA。

要么使用C(自C99以来支持VLA,但自C11以来仅可选支持),要么使用动态数组:std::vector<face>,要么接受您的程序不符合标准的事实。

函数object_info中的变量"face_array"和main的变量"pointer"不是同一个变量。语句"ptr=face_array"不会更改"pointer"的内容。

extern "C" int object_info(int request, face *face_array)
{
if(request == GET_FACE_ARRAY_SIZE)
return 2;
face_array[0].x[0] = 1.1;
face_array[0].y[0] = 0.5;
face_array[0].z[0] = 1.2;
face_array[0].x[1] = 1.6;
face_array[0].y[1] = -0.11;
face_array[0].z[1] = -12;
face_array[0].x[2] = -0.12;
face_array[0].y[2] = 0.24;
face_array[0].z[2] = -0.12;
face_array[0].vertices = 3;
face_array[1].x[0] = -1.1;
face_array[1].y[0] = 0.15;
face_array[1].z[0] = -1.2;
face_array[1].x[1] = -1.6;
face_array[1].y[1] = 0.11;
face_array[1].z[1] = 1.2;
face_array[1].x[2] = 0.12;
face_array[1].y[2] = -0.24;
face_array[1].z[2] = 0.12;
face_array[1].vertices = 3;

}