在C中编码时的常见情况是编写返回指针的函数.如果在运行期间写入函数内发生某些错误,NULL可能会返回以指示错误.NULL只是特殊的内存地址0x0,除了表示特殊条件的出现之外,它从不用于任何东西.
我的问题是,是否有任何其他特殊的内存地址永远不会用于用户态应用程序数据?
我想知道这个的原因是因为它可以有效地用于错误处理.考虑一下:
#include <stdlib.h>
#include <stdio.h>
#define ERROR_NULL 0x0
#define ERROR_ZERO 0x1
int *example(int *a) {
if (*a < 0)
return ERROR_NULL;
if (*a == 0)
return (void *) ERROR_ZERO;
return a;
}
int main(int argc, char **argv) {
if (argc != 2) return -1;
int *result;
int a = atoi(argv[1]);
switch ((int) (result = example(&a))) {
case ERROR_NULL:
printf("Below zero!\n");
break;
case ERROR_ZERO:
printf("Is zero!\n");
break;
default:
printf("Is %d!\n", *result);
break;
}
return 0; …Run Code Online (Sandbox Code Playgroud) 下学期,我将用C进行游戏(特别是C89).来自C#等高级语言,我要做的第一件事就是制作一个实体列表(游戏对象),每一帧,循环遍历每个实体并运行他们的Update和Draw方法.将这种意识形态转换为C,我的想法是开发一个"List"结构,它包含一个指向void指针数组的指针,并使函数能够从列表中添加,获取和删除条目.如果将对象添加到List但数组太小,则将数组重新分配为两倍大的数组.有了这个系统,当我生成一个敌人时,我可以将一个指向其Entity结构的指针添加到List中,然后每个帧循环遍历List,将每个void指针元素作为指向实体的指针,然后将它传递到entity_update(Entity *)和entity_draw(Entity *)相应的方法.
在我看来,只要我100%确定只在List数组中放入指向Entity结构(转换为void指针)的指针,就不会有任何问题......但是当我向同学提到这个时,他说他认为将void指针转换为指向其他东西的指针存在性能缺陷.从我可以看出,在互联网上环顾四周,真正的问题是编译器无法正确优化代码,因为编译器事先知道指针指向哪种类型.在我的情况下,这最终会成为一个问题吗,我想循环通过一个潜在的大型虚拟指针数组,每秒六十次?在实体指针数组中存储指向实体的指针并没有什么大不了的,具有大的,预定义的最大大小,然后进行绑定检查以确保如果没有剩余空间则不会产生敌人数组......但我只是想在开始研究游戏的基本底层引擎之前确定一下.
我有两个cpp类让我们说ClassA和ClassB.我有两个指针,相应地指向那些类,让我们说指针A和指针B. 现在我有一个通用的void*指针,我想根据某些条件指向ClassA或ClassB.在这种情况下获取错误错误C2227:' - > GetPosition'的左边必须指向类/ struct/union /泛型类型是'void*'.
如何避免这种错误?
ClassA {
void GetPosition();
}
ClassB {
void GetPosition();
}
main() {
ClassA *pointerA;
ClassB *pointerB;
void *generic_pointerAorB;
pointerA = GetAddrOfClassA();
pointerB = GetAddrOfClassB()
generic_pointer = pointerA;
//********************** error at the code below ******************************
//error C2227: left of '->GetPosition' must point to class/struct/union/generic type.
//type is 'void *'
generic_pointer->GetPosition();
//*****************************************************************************
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个采用字符串形式的线程argv[1]并将其传递给我的函数.这是我试图传递它的代码.
if(pthread_create(&thread1, NULL, getMax, &argv[1]) != 0){
printf("ERROR createing the thread\n");
return 1;
}
Run Code Online (Sandbox Code Playgroud)
这是我在pthread_create函数中调用的函数.
void * getMax(void * f){
char * fileName = (char*)f;
printf("%s\n\n",fileName);
}
Run Code Online (Sandbox Code Playgroud)
我相信我的问题是当我将它转换回字符指针时.该printf函数打印出几个随机字符.如果我调用函数传递一个字符串就行了.
pthread_create(&thread1, NULL, getMax, "This Works");
Run Code Online (Sandbox Code Playgroud)
如果有人可以解释如何施放argv[1]它,使其行为像一个非常感激的字符数组.
如果编译应用程序以产生x32图像,则根据体系结构整数类型可以是16位宽,32位宽或任何超过2个字节.大小void*将是4(在x32上总是4 ???).这意味着传递int给void*没有问题,但如果事实证明在给定的体系结构void*上比标准体系要宽int(仅保证至少2个字节),那么
C标准n1124 § 6.3.2.3指针
5整数可以转换为任何指针类型.除非先前指定,否则结果是实现定义的,可能未正确对齐,可能不指向引用类型的实体,并且可能是陷阱表示.56)
6任何指针类型都可以转换为整数类型.除非先前指定,否则结果是实现定义的.如果结果无法以整数类型表示,则行为未定义.结果不必在任何整数类型的值范围内.
转换void*为int可能会在以下代码段中产生未定义的行为.
typedef enum tagENUM
{
WSO_1,
WSO_2,
//...
WSO_COUNT
} ENUM;
/* I cannot change handler signature because this is callback. I have to cast void*
* to ENUM however inside */
void handler( int i, int j, void *user_data)
{
ENUM mOperation;
mOperation = (ENUM)reinterpret_cast<int>(user_data);
}
// somewhere
handler( 1, 2, (void*)WSO_1); // UB? We can imagine that …Run Code Online (Sandbox Code Playgroud) 我正在为类创建一个函数,并且参数被声明为void*但是在我需要测试的函数中,如果这个void*是shared_ptr还是unique_ptr,是否有办法测试这种情况?
这就是我到目前为止所做的工作; 我的类是模板类型,不存储任何成员变量.它有一个默认的构造函数,它也可以通过传入一个shared_ptr<Type>或一个来构造,unique_ptr<Type>并且它具有多个allocate()函数,它们执行相同类型的工作.
#ifndef ALLOCATOR_H
#define ALLOCATOR_H
#include <memory>
#include <iostream>
template<class Type>
class Allocator {
public:
Allocator(){}
Allocator( Type type, void* pPtr );
Allocator( std::shared_ptr<Type>& pType );
Allocator( std::unique_ptr<Type>& pType );
// ~Allocator(); // Default Okay
void allocate( std::shared_ptr<Type>& pType );
void allocate( std::unique_ptr<Type>& pType );
void allocate( Type type, void* pPtr );
private:
Allocator( const Allocator& c ); // Not Implemented
Allocator& operator=( const Allocator& c ); // Not Implemented
}; // …Run Code Online (Sandbox Code Playgroud) class testClass
{
public:
void set(int monthValue, int dayValue);
int getMonth( );
int getDay( );
private:
int month;
int day;
};
Run Code Online (Sandbox Code Playgroud)
我有一个简单的课程,如上所示.我尝试将其对象传递给检查它们是否相等的函数.
testClass obj[3];
obj[0].set(1,1);
obj[1].set(2,1);
obj[2].set(1,1);
Run Code Online (Sandbox Code Playgroud)
首先,我试过cout << (obj[0] == obj[1]);但是没有运算符重载,使用模板等是不可能的.所以,我可以使用它们来做但是如何将成员变量传递给void*函数?
bool cmp_testClass(void const *e1, void const *e2)
{
testClass* foo = (testClass *) e1;
testClass* foo2 = (testClass *) e2;
return foo - foo2; // if zero return false, otherwise true
}
Run Code Online (Sandbox Code Playgroud)
我这么想,但我无法解决这个问题.我想比较一下
obj[0].getDay() == obj[1].getDay();
obj[0].getMonth() == obj[1].getMonth();
Run Code Online (Sandbox Code Playgroud)
通过传递.
我正在使用类的RPG游戏我创建了一个结构调用字符,其中包含存储实例的ActionList*.GeneralPlayer是一个类,其中还有一堆其他玩家类继承它.这是我的头文件:
class Battle
{
public:
struct Character
{
char type;//monster or player?
bool alive;
void*instance;//pointer to instance
};
Battle(GeneralPlayer*,AbstractMonster*,int,int,int);
Battle(GeneralPlayer*, AbstractMonster*, int, int);
private:
Character *ActionList;
};
Run Code Online (Sandbox Code Playgroud)
我试图将GeneralPlayer*转换为void*.然而,似乎代码不像我想的那样工作.P和M是那些玩家类的指针数组.
Battle::Battle(GeneralPlayer*P, AbstractMonster*M, int a, int b, int c)
{
a = numP;
b = numM;
c = turn_limit;
ActionList = new Character[numP + numM];
P = new GeneralPlayer[numP];
for (int i = 0; i < numP; i++)
{
ActionList[i] = static_cast<void*>(P[i]);
ActionList[i].type = 'p';
}
for (int i = numP; i < …Run Code Online (Sandbox Code Playgroud) 是否可以交换两个void指针的内容?我尝试通过解除引用两个指针来交换值:
void* a = (void*)50;
void* b = (void*)90;
*a = *b;
Run Code Online (Sandbox Code Playgroud)
但是,最后一行会抛出错误,因为无法取消引用void指针.
我认为可以通过首先将b的值转换为int然后将其强制转换为void*来实现:
void* a = (void*)50;
void* b = (void*)90;
int value = (int)b;
a = (void*)value; //a now equals b
Run Code Online (Sandbox Code Playgroud)
不幸的是,这需要我们知道a和b是什么类型的"假设"(我不知道这样的描述是否正确),在这种情况下,它们是整数.是否可以在不知道其"原始"类型的情况下交换两个void指针的内容?
谢谢.
只嵌入C.
我需要一个函数将无符号数据从每个字节的4字节数组字节复制到输出参数(两者都作为参考传递).函数应该符合MISRA 17.4并且应该支持输出参数的不同无符号整数数据类型(考虑输入将始终具有填充输出的无符号字节的确切数量)
所以我的代码是:
static void copy_array(const void * src, void * dest, const uint8_t lenght_bytes)
{
uint8_t i;
const uint8_t * src_8 = (const uint8_t*)src;
uint8_t * dest_8 = (uint8_t*)dest;
for (i = 0u; i < lenght_bytes; i++)
{
*(dest_8 + i) = *(src_8 + i);
}
}
static void func(void)
{
uint8_t data[] = {0xEFu, 0xCDu, 0x0u, 0x0u};
uint16_t dest_16;
uint32_t dest_32;
copy_array(data, &dest_16, sizeof(dest_16));
data[0] = 0xEFu;
data[1] = 0xCDu;
data[2] = 0xABu;
data[3] = 0x89u;
copy_array(data, …Run Code Online (Sandbox Code Playgroud)