-2

I'm trying to use memcpy to gather an array inside a struct to an array in the global scope. I checked my code, and I can verify that the size I allocate to each array is correct and identical. I can confirm that my problem is with mythrD.sample,but I didn't see anything wrong at this moment. Here is my code snippet:

int main(int argc, char**argv) {
    int numbers = atoi(argv[1]);
    int ps = atoi(argv[2]);
    int i;
    thrD *mythrD = (thrD *) malloc(sizeof(thrD)*ps);
    for (i = 0; i < ps; i++)
    {
        mythrD[i].pid = i;
        mythrD[i].n = numbers;
        mythrD[i].ps = ps;
    }

    long int * array = (long int *) malloc(sizeof(long int)*numbers);
    long int * g_samples = (long int *) malloc(sizeof(long int)*(ps*ps));

    for (i = 0; i < numbers; i++)
    {
            array[i] = rand()%20;
    }

    for (i = 0; i < ps; i++)
    {
        data[i] = (long int*) malloc(sizeof(long int)*chunkSize);
        memcpy(data[i],&array[i*chunkSize], chunkSize*sizeof(long int));
        mythrD[i].chunk = data[i];
    }   

    for (i=0; i < ps; i++) {
        pthread_create(&ids[i], NULL, threadFn1, (void*)&(mythrD[i]));
    }

    pthread_barrier_wait(&mybarrier);

    for (i=0; i < ps; i++) {
        pthread_join(ids[i], NULL);
    }
    pthread_barrier_destroy(&mybarrier);

    for (i = 0; i < ps; i++)
    {
        for (int j = 0; j < ps; j++)
        {
            printf("%ld ",mythrD[i].sample[j]);
        }
    }

    for (i = 0; i < ps; i++) {
        memcpy(&g_samples[i*ps], mythrD[i].sample, ps*sizeof(long int));
    }

    for (i = 0; i< ps*ps; i++) {
        printf("%ld ",g_samples[i]);
    }
    return 0;
}

void* threadFn1(void * chunkD) {
    thrD mychunkD = *(thrD *) chunkD;
    int off_set = mychunkD.n/(mychunkD.ps*mychunkD.ps);
    int chunkSize = mychunkD.n/mychunkD.ps;
    pthread_barrier_wait(&mybarrier);
    mychunkD.sample = (long int *) malloc(sizeof(long int)*(chunkSize/off_set));
    for (int i = 0; i < chunkSize/off_set; i++)
    {
        mychunkD.sample[i] = mychunkD.chunk[i*off_set];
    }
    return NULL;
}

And here is the struct that I defined:

typedef struct threadData{
    long int *chunk;
    long int *sample;
    int pid;
    int n;
    int ps;
} thrD;
RandomEli
  • 1,527
  • 5
  • 30
  • 53
  • `mychunkD.sample` has `chunkSize/off_set` elements allocated, whereas you're iterating to `chunkSize`. – Jean-François Fabre Oct 04 '16 at 17:06
  • You also have an extra indirection it seems. Are you sure the second `&` in `memcpy(&g_samples[i*ps], &(mythrD[i].sample), ps*sizeof(long int));` is necessary. I think `mythrD[i].sample` is already a pointer to your data. – LambdaBeta Oct 04 '16 at 17:07
  • `*mythrD` was allocated memory for `ps` elements, but later on you are indexing up to `ps*ps` elements. – Weather Vane Oct 04 '16 at 17:12
  • I see you have edited that out of your code now. Was that just a copy/paste or typo error? If it was a program error, please do not edit such out of the question.... Now another edit: please do not remove errors from the question that have been pointed out. – Weather Vane Oct 04 '16 at 17:17
  • @WeatherVane It was copy/paste mistake – RandomEli Oct 04 '16 at 17:18
  • @Jean-FrançoisFabre I changed this, it doesn't help. – RandomEli Oct 04 '16 at 17:18
  • @LambdaBeta I changed this already, it doesn't help. – RandomEli Oct 04 '16 at 17:19
  • Rather say: it helps, but it is not enough! – Jean-François Fabre Oct 04 '16 at 17:20
  • Your code sample is not complete (possibly just needs the addition of headers, but I don't know), and I suspect it's not minimal either. Is the threading and sorting essential to the question? The more you can reduce it, the better the chance of someone (possibly even yourself) spotting the cause of the problem - please read how to create a [mcve], then [edit] your post with appropriate code. Thanks. – Toby Speight Oct 04 '16 at 17:20
  • @TobySpeight It is the minimal I can get, gathering is part of the psrs algorithm. – RandomEli Oct 04 '16 at 17:31
  • 1
    It is not minimal. `main(){struct{int *ptr;}x; int *y; x.ptr=malloc(1000); y=malloc(1000); memcpy(y,x.ptr,1000);}` is minimal. Minimal = cut out the stuff we don't need to help you, give us only the code that is broken. It is also not complete, otherwise I could run it by copying it into test.c and compiling it. You may find that by cutting out everything but the bare minimum you fix your problem by accident. So... go do it. :) – LambdaBeta Oct 04 '16 at 18:22

1 Answers1

0

I figured out this problem. I shouldn't allocated the memory in the threadFn, because when we left the thread, that memory will lost. If I allocate mythrD.sample in main, I should be able to maintain that on main scope.

so it should be:

int main ()
{
    for(int i =0; i<ps; i++)
    {
        mythrD[i].sample = (long int *) malloc(sizeof(long int)*ps);   
    }
}
RandomEli
  • 1,527
  • 5
  • 30
  • 53