标签: void-pointers

C Dereference void*指针

嘿伙计们,我是C的新手,对于我的第一个项目,我需要实现一个基于数组的队列.我希望我的队列能够保存任何类型的对象,因此我创建了一个QueueElement结构来保存指向任何类型对象的void指针.我认为一切正常,除了我无法从QueueElement结构中读取'position'和'value'字段.我尝试编译时遇到以下错误.

错误:

Runnable.c: In function `main':
Runnable.c:10: error: dereferencing pointer to incomplete type
Runnable.c:11: error: dereferencing pointer to incomplete type
Run Code Online (Sandbox Code Playgroud)

我很确定我只是没有正确投射.任何帮助表示赞赏.

再次感谢,Pooch

Runnable.c

   #include <stdio.h>
    #include "Queue.h"

    int main(void) {
            int i = 9;
            Queue q = CreateQueue();
            QueueElement e = CreateQueueElement(&i);
            Enqueue(q, e);
            QueueElement f = Dequeue(q);


            /* PROBLEM IS HERE */
            printf("position: %d", f->position);
            printf("value: %d", (int *)(f->value));
            DestroyQueue(q);
            return 0;
    }
Run Code Online (Sandbox Code Playgroud)

Queue.h

#ifndef QUEUE_H
#define QUEUE_H

#include "QueueElement.h"

typedef struct QueueStruct *Queue;

Queue CreateQueue(void);

void DestroyQueue(Queue q); …
Run Code Online (Sandbox Code Playgroud)

c pointers void void-pointers

5
推荐指数
1
解决办法
1万
查看次数

从void**转换为char**有多危险

所以我们知道标准不会强制指针大小相等.(这里这里)(而不是谈论函数指针)

我想知道实际上这可能是一个问题.我们知道void *可以容纳任何东西,所以如果指针大小不同,那将是最大的尺寸.鉴于此,指定void **一个char **意味着麻烦.

我的问题是假设void *char *具有相同的大小是多么危险?实际上有一个架构,这不是真的吗?

此外,16位dos不是我想听到的!;)

c pointers void-pointers

5
推荐指数
1
解决办法
296
查看次数

如何以整数存储内存地址?

这与在找到的问题标题完全相同- 我还想将一个内存地址存储在变量中 - 或者更确切地说,void*在变量中存储一个.但是,我宁愿将它存储在某种形式的int而不是a中string,因为我希望之后再将其转换回指针.

这是因为它是一个类的成员,我想用boost serialize序列化,如果我确实使用了一个void*,boost serialize可能会尝试存储指针所指向的内容,这在我看来不是很明智案件.

我需要32位和64位gcc和MSVC,所以基本上我想知道是否有一个内置的整数类型,它是同一平台上指针的大小.或者,我想我需要IFDEF自己的类型?

c++ void-pointers 32bit-64bit

5
推荐指数
2
解决办法
1万
查看次数

从void*转换为struct

我将struct Person类型的数据传递给链表,因此每个节点的数据指针指向一个结构Person.

struct Person {
char name[16];
char text[24];
};
Run Code Online (Sandbox Code Playgroud)

我试图遍历列表并通过调用打印每个节点中的名称/文本

traverse(&list, &print);
Run Code Online (Sandbox Code Playgroud)

遍历的原型是:

void traverseList(struct List *list, void (*f)(void *));   
Run Code Online (Sandbox Code Playgroud)

列表定义为:

struct List {
struct Node *head;
};
Run Code Online (Sandbox Code Playgroud)

我的print函数接受void*数据:

print(void *data) { .... }
Run Code Online (Sandbox Code Playgroud)

我知道我必须将数据转换为struct Person,对吗?

struct Person *person = (struct Person *)data;
printf("%s", person->name);
Run Code Online (Sandbox Code Playgroud)

我知道这是不够的,因为我得到了"从不兼容的指针类型初始化"警告.在这种情况下,如何成功投出空白*?谢谢.

c struct void-pointers

5
推荐指数
1
解决办法
1万
查看次数

使用 python ctypes 和 libc 写入指向二进制文件的空指针

我正在使用 python ctypes 和 libc 与供应商提供的 DLL 文件进行交互。DLL 文件的目的是从相机获取图像。

图像采集似乎运行没有错误;我遇到的问题是访问数据。

图像采集函数将 ctypes.c_void_p 作为图像数据的参数。

简化如下:

"""
typedef struct AvailableData
{
    void* initial_readout;
    int64 readout_count;
} imageData;
"""

class AvailableData(ctypes.Structure):
    _fields_ = [("initial_readout", ctypes.c_void_p), 
                ("readout_count", ctypes.c_longlong)]

"""
Prototype
Acquire(
CamHandle                 camera,
int64                       readout_count,
int                       readout_time_out,
AvailableData*         available,
AcquisitionErrorsMask* errors );
"""

>>> imageData = AvailableData()
>>> Acquire.argtypes = CamHandle, ctypes.c_longlong, ctypes.c_int, 
         ctypes.POINTER(AvailableData), ctypes.POINTER(AcquisitionErrorsMask)
>>> Acquire.restype = ctypes.c_void_p

>>> status = Acquire(camera, readout_count, readout_time_out, imageData, errors)
Run Code Online (Sandbox Code Playgroud)

我不完全理解该函数在做什么,因为在我运行该函数后,它imageData.initial_readout似乎是一个类型“long”(甚至不是 ctypes.c_long:只是“long”)。然而,它也有一个与之相关的价值。我假设这是存储数据的起始地址。

>>> type(imageData.initial_readout)
<type …
Run Code Online (Sandbox Code Playgroud)

python ctypes libc fwrite void-pointers

5
推荐指数
1
解决办法
2898
查看次数

对C中的指针和泛型(void)指针感到困惑

我错过了几个课程,并没有真正理解流动的演讲幻灯片关于void指针的例子.

  1. 在"no,no,no"这一行中,为什么我们不能因为P被分配了一个真正的指针类型q而不需要P?

  2. 在"??"行中,将指针强制转换为整数是否合法?(我认为它可以编译,因为C不会检查强制转换,但不知道它将获得什么样的结果

在这个例子中 ,整数指针转换为
他铸造的整数*p = 10; a =(int)p; 并且有人回答说a将是一个非常大的价值.但在我的情况下,是(int)*p ...是否与我上面给出的例子相同?

  1. 在最后一行,我对表达式感到困惑.*((int*)p)实际上是= p吗?谢谢!

在此输入图像描述

在此输入图像描述

c pointers generic-programming void-pointers

5
推荐指数
1
解决办法
307
查看次数

reinterpret_cast std :: function*来往于void*

当我从主可执行文件中调用std :: function时,通过将其地址转换为/从中,我在插件中遇到段错误void*.我可以在几个自包含的行中重现这个问题:

#include <iostream>
#include <functional>

int main()
{
    using func_t = std::function<const std::string& ()>;

    auto hn_getter = func_t{[]() {
        return "Hello";
    }};

    auto ptr = reinterpret_cast<void*>(&hn_getter);

    auto getter = reinterpret_cast<func_t*>(ptr);
    std::cout << (*getter)() << std::endl;   // Bang!

    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

即使我正在使用原始类型,它仍然是segfaulting.谁能看到我哪里出错了?

c++ void-pointers reinterpret-cast std-function

5
推荐指数
1
解决办法
663
查看次数

检查使用 static_cast 将 void* 转换为 Object 是否成功

我正在开发一个将从 C# 调用的 C++ 插件。我尝试移植的 API 带有数百个函数,其中大多数只是具有相同名称但具有不同数据类型(如 、intfloat)的重载char

我不想一遍又一遍地在 C++ 和 C# 端编写相同的代码但使用不同的数据类型,而是想使用一个带有通用指针的函数重载。我的目标是使用static_castfromvoid*intfloat然后char使用第一个成功的。

C++ 端的一个简单测试函数:

void calculate(void* input1, void* input2)
{
    float *i1 = static_cast<float*>(input1);
    if(i1==NULL)
    std::cout<<"Bad"<<std::endl;
    else
    std::cout<<*i1<<std::endl;
}

int main()
{
   int input1 = 5;
   int input2 = 10;

   calculate(&input1,&input2);

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

这应该输出“BAD”,但它似乎显示“7.00649e-45”,我认为这是一种未定义的行为。失败static_cast了,我不知道如何检查它是否成功。检查它是否NULL在这种情况下没有帮助。

是否可以检查void*反对static_cast是否成功?如果是这样,怎么办?

笔记

这不是这个问题的重复。我不想从 中找出对象的类型void*。我只是想检查转换是否static_cast …

c++ pointers casting void-pointers

5
推荐指数
1
解决办法
4351
查看次数

当一次只需要一种类型时,保持指向不同类型的指针的最佳方法是什么?

我处于一种情况,我需要一个指向未知类型对象的指针作为另一个类的成员。但是有效对象类型的列表在编译时是已知的。

说我有:

// A class templated on T
template<class T> class obj;

// Now assume there are some objects of types obj<...> somewhere else
obj<int> obj1;
obj<double> obj2;

// Now, manager needs to create a pointer for these objects
// in a specific manner at construction-time

// Say, we have to choose a canonical object (and set the other as secondary)

// manager shouldn't be templated on T because It needs
// to have multiple members of type obj<...>
template<class …
Run Code Online (Sandbox Code Playgroud)

c++ pointers void-pointers unions c++11

5
推荐指数
1
解决办法
143
查看次数

是否可以以不会导致 UB 的方式分配未初始化的数组?

在 C++ 中实现某些数据结构时,需要能够创建一个包含未初始化元素的数组。正因为如此,拥有

buffer = new T[capacity];
Run Code Online (Sandbox Code Playgroud)

不适合,因为new T[capacity]初始化数组元素,这并不总是可能的(如果 T 没有默认构造函数)或期望的(因为构造对象可能需要时间)。典型的解决方案是分配内存并使用placement new。

为此,如果我们知道元素的数量是已知的(或者至少我们有一个上限)并在堆栈上分配,那么,据我所知,可以使用对齐的字节或字符数组,然后使用std::launder访问成员。

alignas(T) std::byte buffer[capacity];
Run Code Online (Sandbox Code Playgroud)

但是,它只解决了栈分配的问题,并没有解决堆分配的问题。为此,我假设需要使用对齐新,并写这样的东西:

auto memory =  ::operator new(sizeof(T) * capacity, std::align_val_t{alignof(T)});
Run Code Online (Sandbox Code Playgroud)

然后将其转换为std::byte*orunsigned char*T*

// not sure what the right type for reinterpret cast should be
buffer = reinterpret_cast(memory);
Run Code Online (Sandbox Code Playgroud)

但是,有几件事我不清楚。

  1. reinterpret_cast<T*>(ptr)如果 ptr 指向可与 T 进行指针互转换的对象,则定义结果。(请参阅此答案https://eel.is/c++draft/basic.types#basic.compound-3)了解更多详细信息。我假设,将其转换T*为无效,因为 T 不一定与 new 的结果是指针可互转换的。但是,它是否为char*或定义明确std::byte
  2. 当将 的结果转换new为有效的指针类型(假设它不是实现定义的)时,它是否被视为指向数组第一个元素的指针,或者只是指向单个对象的指针?虽然,据我所知,在实践中很少(如果有的话)很重要,但存在语义差异,pointer_type + integer …

c++ memory-management void-pointers dynamic-memory-allocation reinterpret-cast

5
推荐指数
1
解决办法
165
查看次数