简体   繁体   中英

Segmentation fault when allocating memory for a 2D array

This program takes arguments from the command line and displays their prime factors using threads. I am using a struct to pass info between threads. The struct has a 2D array that holds the arguments and then their factors. The way i'm allocating now allows me to access two of my arguments and the gives me a Segmentation fault (Location of Segmentation fault is noted in the code). What am I doing wrong? All code is provided below.

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

// Global variables
#define MAX_FACTORS (11)
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;

struct Buffer {
    int **factors;
    int size;
};


void *factor ( void *buffer );
void *displayFactors (void *factors);


// MAIN
int main (int argc, char* argv[]) {
    // Create Buffer
    struct Buffer *buffer;
    buffer = malloc(sizeof(struct Buffer));
    buffer->size = argc - 1;

    // Allocate memory for factors 2d array
    buffer->factors = malloc(buffer->size);

    for( int i = 0; i < buffer->size; i++) {
        buffer->factors[i] = calloc(MAX_FACTORS, sizeof(int));
    }

    pthread_mutex_lock(&mutex1);

    if(buffer->size > 0) {
        for(int i = 1; i < argc; i++){
            buffer->factors[i - 1][0] = atoi(argv[i]);
            // ---SEGMENTATION FAULT OCCURS HERE AFTER LOOPING TWICE.----
        }
    }
    else
        return 0;

    pthread_mutex_unlock(&mutex1);

    pthread_t producer;
    pthread_t consumer;

    pthread_create(&producer, NULL, factor, (void*)buffer);
    pthread_create(&consumer, NULL, displayFactors, (void*)buffer);

    pthread_join(producer, NULL);
    pthread_join(consumer, NULL);

    free(buffer->factors);

    return 0;
}


// PRODUCER
void *factor ( void *buffer ) {
    struct Buffer *prod_buffer = (struct Buffer*)buffer;

    pthread_mutex_lock(&mutex1);

    // find numbers to factor factors
    int i = 0;
    while(i < prod_buffer->size) {
        // printf("Numbers to factor: %d\n", prod_buffer->factors[i][0]);
        prod_buffer->factors[i][0] = prod_buffer->factors[i][0];
        i++;
    }

    // Factor numbers
    for(int i = 0; i < prod_buffer->size; i++) {
        int j = 1;
        int toFactor = prod_buffer->factors[i][0];
        while(toFactor % 2 == 0) {
            prod_buffer->factors[i][j] = 2;
            toFactor = toFactor / 2;
            j++;
        }
        for(int k = 3; k <= toFactor; k += 2) {
            while (toFactor % k == 0) {
                prod_buffer->factors[i][j] = k;
                toFactor /= k;
                j++;
            }
        }
    }
    pthread_mutex_unlock(&mutex1);
    return NULL;
}


// CONSUMER
void *displayFactors (void *buffer) {
    struct Buffer *cons_buffer = (struct Buffer*)buffer;

    for (int i = 0; i < cons_buffer->size; i++) {
        printf("%d: ", cons_buffer->factors[i][0]);
        for (int j = 1; j < MAX_FACTORS; j++){
            if(cons_buffer->factors[i][j] != 0) printf("%d ", cons_buffer->factors[i][j]);
        }
        printf("\n");
    }
    return NULL;

}

EDIT-- The arguments i've been testing with are 4, 13, 46, 72, 5, and 12. The result should display: 4: 2 2 13: 13 46: 2 23 72: 2 2 2 3 3 5: 5 12: 2 2 3

Thanks for the help!

I use gdb to debug your code, I found that the size of buffer->factors is 8, that is not enough.

you should do

buffer->factors = malloc(buffer->size*sizeof(int *));

This segmentation fault error can fix.

Also,There is another bug in your code. if the consumer execute first, the output will empty, so you need use the cond to make the producer exectue first.

Here some tips:

pthread_cond_t product = PTHREAD_COND_INITIALIZER; /*global*/ 
pthread_cond_signal(&product);  /*In factor function*/

Also the displayFactors need to add a mutex .

/*in displayFactors function*/
pthread_cond_wait(&product, &mutex1); 

And where to put those statements, you should figure it out by yourself. Hope that can help you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM