指向int和string的Typecast无效指针

指向int和string的Typecast无效指针,c,pointers,C,Pointers,我要做的是将值存储在元素strucz数组中(该数组有一个成员void*data) 我让数组有3个元素 Element* array = malloc(3 * sizeof(Element)); 我知道如果数据是int,你可以这样做,但如果数据是空的,你怎么做* array[0].data = 65; 我试过打字 ((*int)(array[0].data)) = 65; 但我在'int'之前得到了预期表达式的消息 我的第二个问题是如何在元素结构中存储字符串(我不能使另一个成员成为字符串,它

我要做的是将值存储在元素strucz数组中(该数组有一个成员void*data)

我让数组有3个元素

Element* array = malloc(3 * sizeof(Element));
我知道如果数据是int,你可以这样做,但如果数据是空的,你怎么做*

array[0].data = 65;
我试过打字

((*int)(array[0].data)) = 65;
但我在'int'之前得到了预期表达式的消息

我的第二个问题是如何在元素结构中存储字符串(我不能使另一个成员成为字符串,它必须使用void指针)

我可以用strcopy或sscanf吗

如果我做错了什么,请在下面的主样本中选择

编辑

抱歉,我应该添加数据将使用循环添加(迭代基于用户输入,因此arrayOfElements可能有5,8,20个ect元素),基于用户3386109答案

Element* arrayOfElements = malloc(3 * sizeof(Element));
arrayOfElements[0].data = malloc( sizeof(int) );
int *ptr = arrayOfElements[0].data;
*ptr = 65;
工作非常完美,但如果我想制作ArrayFelments[1]。数据=67

Element* arrayOfElements = malloc(3 * sizeof(Element));
 arrayOfElements[1].data = malloc( sizeof(int) );
 int *ptr = arrayOfElements[1].data;
 *ptr = 76;

我不能重复使用*ptr,即使我使用免费(ptr),如果您不知道ArrayFelments将有多少元素,是否还有其他方法可以重复使用*ptr?

您问题中的
malloc
创建了一个包含三个结构的数组。每个
struct
都有一个名为
data
的未初始化指针。在使用该指针之前,必须再次调用
malloc
对其进行初始化

要存储
int

array[0].data = malloc( sizeof(int) );
int *ptr = array[0].data;
*ptr = 65;
要存储字符串,请执行以下操作:

array[0].data = malloc( strlen(str) + 1 );
strcpy( array[0].data, str );

下面是一个完整的示例,演示如何初始化数组,打印数组的元素,然后
释放
数组。请注意,
ptr
只是一个临时变量,用于避免与强制转换和取消引用
void*
相关的糟糕语法。(一个好的编译器将优化
ptr
变量。)

int main(无效)
{
int*ptr;
char*str=“你好”;
元素*数组=malloc(3*sizeof(元素));
数组[0]。数据=malloc(sizeof(int));
ptr=array[0]。数据;
*ptr=65;
数组[1]。数据=malloc(strlen(str)+1);
strcpy(数组[1]。数据,str);
数组[2]。数据=malloc(sizeof(int));
ptr=数组[2]。数据;
*ptr=76;
ptr=array[0]。数据;
printf(“%d\n”,*ptr);
str=数组[1]。数据;
printf(“%s\n”,str);
ptr=数组[2]。数据;
printf(“%d\n”,*ptr);
对于(int i=0;i<3;i++)
空闲(数组[i]。数据);
自由(数组);
}

你现在处境艰难。C标准(草案n1256)在6.3转换中规定:

2将操作数值转换为兼容类型不会导致值或 代表

以及后面的6.3.2.3指针:

5整数可以转换为任何指针类型。除非之前另有规定,否则 结果是定义了实现,可能未正确对齐,可能未指向 引用类型的实体,可能是陷阱表示。56)

6任何指针类型都可以转换为整数类型。除非之前另有规定,否则 结果是定义了实现。如果结果不能用整数类型表示, 该行为未定义。结果不必在任何整数类型的值范围内

标准库甚至定义了一个特殊的整数类型
intptr\u t
,它可以接受而不丢失任何指针,但这只是一个信息部分

无论如何,在所有常见的实现中,可以安全地将整数来回转换为指针,前提是:

  • 如果它最初是一个整数,您永远不会尝试引用它,而是在使用它之前将其转换回整数(与原始类型相同)。由于演员不应改变表现形式,您将获得原始值
  • 如果它最初是一个指针,您不会尝试将其作为整数使用,除非您的实现确保没有陷阱表示—公共实现允许它
  • 整数类型接受所有指针表示-如果不确定,请使用
    intptr\u t
因此,您可以:

array[0].data = (void *) (intptr_t) 65;
后来

int i = (intptr_t) array[0].data;

“在使用该指针之前,必须通过另一次调用malloc来初始化它”是因为数据是空的*还是通常我必须这样做?通常是这样。指针在初始化为指向某个对象之前不能使用。初始化指针还有其他方法,但对于您的示例,使用
malloc
是正确的选择。createArrayArray.c:26:5:警告:格式“%s”要求参数类型为“char*”,但参数2的类型为“int”[-Wformat=]printf(“%s\n”,*str);当我运行它时,它打印65,但我得到一个segfault@CrispyCashew是的,已经修复,
*str
应该是
str
,在
printf
中。复制/粘贴错误。@CrispyCashew随时都可以,很乐意帮助:)我必须使用C89(-gcc中的ansi)您的程序设计有一些根本性的错误。如果您出于任何目的使用
void*
,您必须有一个计划来知道它指向什么类型,否则您的程序将不会做任何有用的事情。您通过
void*
存储杂项类型,然后呢?你怎么知道每一个这样的指针指向什么?哦,我有办法追踪它是什么类型的,图中所示的只是一小部分。但我理解你的担忧
int main( void )
{
    int *ptr;
    char *str = "hello";

    Element *array = malloc(3 * sizeof(Element) );

    array[0].data = malloc( sizeof(int) );
    ptr = array[0].data;
    *ptr = 65;

    array[1].data = malloc( strlen(str) +  1 );
    strcpy( array[1].data, str );

    array[2].data = malloc( sizeof(int) );
    ptr = array[2].data;
    *ptr = 76;

    ptr = array[0].data;
    printf( "%d\n", *ptr );
    str = array[1].data;
    printf( "%s\n", str );
    ptr = array[2].data;
    printf( "%d\n", *ptr );

    for ( int i = 0; i < 3; i++ )
        free( array[i].data );
    free( array );
}
array[0].data = (void *) (intptr_t) 65;
int i = (intptr_t) array[0].data;