我可以访问并将数据写入void**吗?

问题描述 投票:0回答:3

我尝试分配内存,但我不能只存储一种类型的指针,所以我必须存储

void*
,并访问这个指针
void **
指针。

我尝试写作,使用:

*((int *)(void *))

上的指针空指针重新部署(解释)为整数指针

)。

代码示例:
void **d = malloc(sizeof(int) * 10);
 printf("%d\n", sizeof(*( (int *) *d )));

输出:
4

void **d = malloc(sizeof(int) * 10);
*( (int *) *d ) = 1;

输出:
segmentation fault (core dumped)


我想知道,是否可以访问这个内存,或者如何存储数据,未知的类型。
arrays c pointers memory
3个回答
2
投票

此代码片段 printf 
4
 因为 
sizeof
 运算符仅返回作为参数传递的任何内容的内存大小。
在这种情况下,您基本上要求的是 
int

的大小(在您的平台上为 4):
void** d = malloc(sizeof(int) * 10);
printf("%d\n", sizeof(*((int*)*d)));

使用此代码片段,您会遇到分段错误,因为 
*d

无处指向:
void **d = malloc(sizeof(int) * 10);
*( (int *) *d ) = 1;

您可能想要这个(不需要双指针):
void* d = malloc(sizeof(int) * 10);
*((int*)d) = 123;
printf("%d\n", *((int*)d));

输出:
123


0
投票

我认为你在这里混淆了一些事情。
  1. “sizeof”是什么以及它的作用。 sizeof 是一个 C 编译时运算符(不是函数),它返回传递给它的 表达式 的大小。该运算符在编译时进行处理,并且对堆的状态一无所知(这是 malloc 在运行时从 分配的内容)。 如果您期望 printf 返回“10”(您分配的 int 数组的大小),您会感到失望。 C 希望您跟踪您分配的内容并保持在您从 malloc 请求的范围内。

  2. malloc 和 C 类型系统。 malloc 函数并不真正关心你的数据是什么类型,它分配一个以字节为单位的内存块,并期望你正确使用它。 当谈到指针时,C 类型系统主要是记录意图而不是用法。 void 类型表示非区分数据,并且很有用,因为它允许您绕过类型检查。 malloc函数返回void*,因为它可以分配给任何其他指针类型(不会生成警告)。 如果你想要一个 int 数组,你可以声明变量 int* 。 您通常不会声明事物 void*。

  3. 声明和访问(取消引用)指针。 声明显示结构,而访问(称为取消引用指针)显示用法(可能有更好的方法来表达)。 因此,您将 d 变量声明为“void *”,这意味着预期的结构是一个指向另一个指针的指针(在本例中是 C 表示为指针的数组)。 当您分配(调用 malloc)时,您只能返回一个指针。 您用两个指针定义了一个结构,但只用一个指针设置该变量。 你的另一个指针在哪里? ...这是由数组使用所暗示的。 考虑像这样“((int *) d)[0]”来引用它。 它将 d 转换为 int* (或数组),然后使用数组表示法(指针偏移量)来访问它。 您可以将强制转换视为第一个指针,将数组引用视为第二个指针。

考虑这样的事情:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    #define MyArrayCount 10
    #define MyMemorySize sizeof(int) * MyArrayCount
    int* d = malloc(MyMemorySize);
    printf("Array size: %d  memory needed: %ld\n", MyArrayCount, MyMemorySize);
    d[0] = 100;
    d[MyArrayCount - 1] = 9999;    
    printf("[0]=%d  [max]=%d\n", d[0], d[MyArrayCount - 1]);
    
    printf("address as int*:   %p\n", d);
    printf("address as void**: %p\n", (void**) d);    

    return 0;
}

这将产生类似这样的输出:

Array size: 10  memory needed: 40
[0]=100  [max]=9999
address as int*:   0x5ee63a0792a0
address as void**: 0x5ee63a0792a0

注意,如果由于某种原因您需要通过 void** 可寻址的内存块,您可以将其转换为该内存块,它将是相同的内存地址。


-1
投票
  1. 您可以访问它:
int main()
{
    void **d = malloc(sizeof(int) * 10);
    ((int *)d)[5] = 45;
    printf("%d\n", ((int *)d)[5]);
}
  1. sizeof(pointer)
    只给出了指针本身的大小,而不是分配的内存的大小。
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.