12

I am confuse on how to read the pointers copied in an array using memcpy. Following is what I have tried, but does not work.

Basically, I have allocated block of memory in which I am copying pointers similar to array fashion, but during retrial it is not working. While this works with basic data types properly

I want to store anything in the element block, It can be either integers or pointers.

#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;
}

In the above code f1_int works fine but f2_int_ptr does not work.

Avinash
  • 12,851
  • 32
  • 116
  • 186
  • Note: All this typecasting to and from `void *` (and the macro) is not making your code pretty nasty. Is there any reason you're using `void *` everywhere? – Oliver Charlesworth Apr 01 '11 at 10:43
  • This works for all basic types, but not working only for pointers. – Avinash Apr 01 '11 at 10:44
  • You should try to clarify your code if you intend it to be read. C being a hoax (http://www.gnu.org/fun/jokes/unix-hoax.html) is not an argument to code that way. – mouviciel Apr 01 '11 at 10:52

4 Answers4

8

f2_int_ptr() needs to become this:

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 );
    }
}

Note the subtle changes to the memcpy() arguments.

Note: I really, really, really, wouldn't write code like this! It's incredibly difficult to follow.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • If i use pointer-to-pointer then I have to make sure always that elements going into the block is always allocated, I cannot have elements from the stack. – Avinash Apr 01 '11 at 10:56
  • @Oli Charlesworth, I agree that this is not good code, but with your solution, It means I have to keep to different approaches for copy and retrieval for basic type and pointer type. – Avinash Apr 03 '11 at 21:49
  • @Avinash: Basic types and pointer types are fundamentally different. It's still not clear why you wish to be able to treat them the same. What are you trying to achieve here? – Oliver Charlesworth Apr 03 '11 at 21:59
  • I am trying to write a stl vector in C, and I could do it if client allocating memory on the heap and pass as an element to me. But I want it to work with basic datatype and there should not be special way to pass variables on the stack or heap variables. – Avinash Apr 05 '11 at 13:33
  • there is way to do this using MACROS but i was looking for option which avoid MACROS. – Avinash Apr 05 '11 at 13:55
0

Code is very ugly, so I dont even know how it should works but: Why are u using &v here:

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

v is pointer itself:

int *v = (int*)0;
IProblemFactory
  • 9,551
  • 8
  • 50
  • 66
  • It dumps without that. I wanted to read from the array, I am not sure how to do that and array has pointer copied. – Avinash Apr 01 '11 at 10:48
0

If you are storing the pointers in the elemnts, I think the final memcpy needs to use &v to copy the element to the pointer v. Similar to 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
  • 509
  • 2
  • 6
  • 16
0

thanks Guys, it worked finally. i guess i have not allocated the space where to copy 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 );
    }
}
Avinash
  • 12,851
  • 32
  • 116
  • 186
  • because you have a memory leak. You are not freeing `v` in the first or second loop. Also, you are storing `int` values in `elements`, not `int *`. See my answer. – Oliver Charlesworth Apr 01 '11 at 11:56