Home > Enterprise >  Copying memory of adresses with memcpy
Copying memory of adresses with memcpy

Time:11-16

Base function:

template <typename T>
T** shifting (T* in, int size, int dist, int pos) {
    auto out = new T* [size];
    int k = (pos-1) * size/dist;
    for (int i{0}; i < size;   i) {
        if (i k >= size) {
            out[i] = &in[k i-size];
        } else {
            out[i] = &in[k i]
        }
    }
    return out;
}

This function is creating an array of pointers out to elements of array in in a specific order, I wondered if there would be a faster approach with memory manipulation, so I tried something different.

New function:

template <typename T>
T** stuff(T* in, int size, int dist, int pos) {
    int helper = size/dist;
    auto out = new T* [size];
    for (int i{0}; i < dist; i  ) {
        if (pos   i < size) {
            memcpy(out   i - pos   dist, in i*helper, helper * sizeof(T*));
        } else {
            memcpy(out   i - pos, in i*helper, helper * sizeof(T*));
        }
    }
    return out;
}

However this is not giving an array of adresses, but rather converts the values behind the addresses to pointers so I get the value of the element as a pointer. On closer inspection this behaviour should not be otherwise, but I can't think of a way to get it to work.

Thanks for any help.

CodePudding user response:

Your new loop body (before your edit, but my analysis remains basically the same) is:

memcpy(out   i - pos   (pos   i < size ? dist: 0), in i*helper, helper * sizeof(T*));

Expanding that for readability (which will not hurt performance, so you should do it too):

T** dest = out   i - pos   (pos   i < size ? dist: 0);
T* src = in   i * helper;
memcpy(dest, src, helper * sizeof(T*));

By writing it out with types, now you can see that the types are not compatible (T** and T*). What you're trying to do is copy addresses to particular locations of in, but you can't do that in chunks like this because those addresses don't exist as numbers in memory yet, you need to create them!

Your best bet is to stick with your original code, which is clearer. If there is a performance problem, tell us what level of optimization you're compiling with, what are the input sizes you're using, what is the time taken by this function, and how much is your time budget?

CodePudding user response:

I don't know if that's exactly what you're looking for, but this will run a bit faster and is somewhat easier to read, and reason about.

template <typename T>
T** shifting (T* in, int size, int dist, int pos) {
    auto out = new T* [size];
    int k = (pos-1) * size/dist;

    int i, j;
    for (i = 0, j = k; i < size - k;   i,   j)
        out[i] = &in[j];

    for (j = 0; i < size;   i,   j)
        out[i] = &in[j];

    return out;
}
  • Related