memcpy和指针

12

我很困惑如何使用memcpy读取复制到数组中的指针。以下是我的尝试,但不起作用。

基本上,我已经分配了一块内存,在其中类似于数组方式复制指针,但在检索时它不起作用。而这对基本数据类型有效。

我想将任何东西存储在element块中,可以是整数指针

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

#define INDEX(x)  ((char *)elements + (sizeof(int*) * (x)))
int size = 10;

void f2_int_ptr() {    
    int i = 0;
    void *elements = (void*)malloc(size * sizeof(int*));
    for ( i = 0; i < size; i++ ) { 
       int *v = ( int *) malloc ( sizeof(int));
       memcpy ( v, &i, sizeof ( int ));


       memcpy ( INDEX(i) , v,  sizeof (int*));
    }
    for ( i = 0; i < size; i++ ) { 
        int *v = (int*)0;
        memcpy ( v, INDEX(i), sizeof(int *));
        printf ( "%d\n", *v );
    }
}
void f1_int() {
    int i = 0;
    void *elements = (void*)malloc(size * sizeof(int));
    for ( i = 0; i < size; i++ ) { 
       memcpy ( INDEX(i) , &i,  sizeof (int));
    }
    for ( i = 0; i < size; i++ ) { 
        int v;
        memcpy ( &v, INDEX(i), sizeof ( int ));
        printf ( "%d\n", v );
    }
}
int main(){
    f1_int();
    f2_int_ptr();
    return 0;
}
在以上代码中,f1_int 可以正常工作,但 f2_int_ptr 不能正常工作。

注意:所有这种针对void *的类型转换(以及宏)都会使您的代码变得非常丑陋。您使用void *的原因是什么? - Oliver Charlesworth
这适用于所有基本类型,但仅对指针无效。 - Avinash
如果你打算让别人读懂你的代码,那么你应该尽量澄清它。C语言是一个骗局(http://www.gnu.org/fun/jokes/unix-hoax.html)并不是编写代码的理由。 - mouviciel
4个回答

8

f2_int_ptr()需要变成这样:

void f2_int_ptr() {
    int i = 0;
    void *elements = malloc(size * sizeof(int*));

    for ( i = 0; i < size; i++ ) { 
       int *v = malloc ( sizeof(int));
       memcpy ( v, &i, sizeof ( int ));
       memcpy ( INDEX(i) , &v,  sizeof (int*));
    }

    for ( i = 0; i < size; i++ ) {
        int *v;
        memcpy ( &v, INDEX(i), sizeof(int *));
        printf ( "%d\n", *v );
    }
}

请注意对memcpy()参数的微小更改。
注:我真的,真的,真的不会写这样的代码!它非常难以理解。

如果我使用指向指针的指针,那么我必须始终确保进入块的元素已经分配,不能使用来自堆栈的元素。 - Avinash
@Oli Charlesworth,我同意这不是好的代码,但是使用你的解决方案,这意味着我必须为基本类型和指针类型的复制和检索保持两种不同的方法。 - Avinash
@Avinash:基本类型和指针类型在本质上是不同的。仍然不清楚您为什么希望能够将它们视为相同的。您在这里想要实现什么? - Oliver Charlesworth
我正在尝试在C语言中编写一个STL向量,如果客户端在堆上分配内存并将其作为元素传递给我,我可以做到这一点。但是我希望它能够使用基本数据类型,并且不应该有特殊的方法来传递堆栈变量或堆变量。 - Avinash
有一种使用宏的方法可以实现这个,但我正在寻找避免使用宏的选项。 - Avinash

0

代码非常丑陋,所以我甚至不知道它应该如何工作,但是:你为什么在这里使用&v:

memcpy ( &v, INDEX(i), sizeof ( int ));

v是指针本身:

int *v = (int*)0;

它没有转储。我想从数组中读取,但我不确定如何做,而且数组已经被复制了指针。 - Avinash

0
如果您正在将指针存储在元素中,我认为最终的memcpy需要使用&v将元素复制到指针v。类似于v=elements[i]。
void f2_int_ptr() {    
    int i = 0;
    void *elements = (void*)malloc(size * sizeof(int*));
    for ( i = 0; i < size; i++ ) { 
       int *v = ( int *) malloc ( sizeof(int));
       memcpy ( v, &i, sizeof ( int *));


       memcpy ( INDEX(i) , &v,  sizeof (int*));
    }
    for ( i = 0; i < size; i++ ) { 
        int *v = (int *)0;
        memcpy ( &v, INDEX(i), sizeof(int *));
        printf ( "%d\n", *v );
    }
}

好的。通过编辑,我想我明白你想做什么了(将指针复制到元素中),所以我已经更新了。 - sickgemini
我猜这也会丢失,所以在取回元素之前我需要先分配v。 - Avinash
没想到你需要这样做,因为你已经有了原始的分配。 - sickgemini

0

谢谢大家,终于成功了。 我猜我没有分配空间来复制memcpy。

void f2_int_ptr() {    
    int i = 0;
    void *elements = (void*)malloc(size * sizeof(int*));
    for ( i = 0; i < size; i++ ) { 
       int *v = ( int *) malloc ( sizeof(int));
       memcpy ( v, &i, sizeof ( int ));

       memcpy ( INDEX(i) , v,  sizeof (int*));
    }
    for ( i = 0; i < size; i++ ) { 
        int *v = ( int *) malloc (sizeof(int*));
        memcpy ( v, INDEX(i), sizeof(int*));
        printf ( "%d\n", *v );
    }
}

因为你有内存泄漏。在第一次或第二次循环中,你没有释放 v。此外,你正在将 int 值存储在 elements 中,而不是 int *。请参考我的答案。 - Oliver Charlesworth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接