Разобраться с динамическим выделением памяти в массиве строк - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Здравствуйте. Помогите разобраться с динамическим выделением памяти в массиве строк. Нашел в сети код очереди. Правда, там был тип хранящихся значений int. Я же переделал так, чтобы хранились не целые числа, а строки. Вот код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
struct queue {
 
    char** v;
    int head;
    int tail;
    int size;
    int maxsize;
};
 
/* queue create: Creates an empty queue. */
struct queue *queue_create(int maxsize) {
 
    struct queue *q = malloc(sizeof (*q));
    if (q != NULL) {
    
        q->v = (char**) malloc(sizeof(char*) * (maxsize+1));
        if (q->v == NULL) {
        
            free(q);
            return NULL;
        }
        q->maxsize = maxsize;
        q->size = 0;
        q->head = maxsize + 1;
        q->tail = 0;
    }
    return q;
}
 
/* queue_free: Removes queue. */
void queue_free(struct queue *q) {
 
    free(q->v);
    free(q);
}
 
/* queue_size: Returns size of a queue. */
int queue_size(struct queue *q) {
    return q->size;
}
 
/* queue_enqueue: Add item to the queue. */
int queue_enqueue(struct queue *q, char* value) {
    
    if (q->head == q->tail + 1) {
    
        fprintf(stderr, "queue: queue overflow\n");
        return -1;
    }
    q->v[q->tail++] = (char*) malloc(strlen(value)+1);
    strcpy(q->v[q->tail++],value);
    q->tail = q->tail % (q->maxsize + 1);
    q->size++;
    return 0;
}
 
/* queue_dequeue: Gets item from the queue. */
char* queue_dequeue(struct queue *q) {
    char *val;
    if (q->head % (q->maxsize + 1) == q->tail) {
        /* queue is empty */
        fprintf(stderr, "queue: Queue is empty\n");
        return NULL;
    }
    q->head = q->head % (q->maxsize + 1);
    q->size--;
    strcpy(val,q->v[q->head++]);
    free(q->v[q->head++]);
    return val;
}
 
int main() {
    struct queue *q;
    int i;
    char* val;
 
    q = queue_create(10);
    
    val = "stroka\n";
    for (i=0; i<10; i++) {
        queue_enqueue(q, val);
    }
    
    fprintf(stdout, "Очередь: \n");
    for (i=0; i<10; i++) {
    
        val = queue_dequeue(q);
        fprintf(stdout, "%s\n", val);
    }
    
    queue_free(q);
    return 0;
}
В итоге, программа валится в функции queue_enqueue на строке strcpy(q->v[q->tail++],value); Ошибка сегментирования. Явно я что-то намудрил с выделением памяти, но на вид вроде все правильно. Может, у вас глаз наметан лучше...

Решение задачи: «Разобраться с динамическим выделением памяти в массиве строк»

textual
Листинг программы
#include <stdio.h>
#include <glib.h>
 
int main(void) {
    char buf[BUFSIZ], * ptr;
    GQueue * queue = g_queue_new();
    
    while ( printf("> ") > 0 && fgets(buf, BUFSIZ, stdin) && *buf != '\n' )
        g_queue_push_tail(queue, g_strdup(buf));
    
    while ( ptr = g_queue_pop_head(queue) ) {
        printf("%s", ptr);
        g_free(ptr);
    }
    
    g_queue_free(queue);
    return 0;
}

Объяснение кода листинга программы

  1. Включаются необходимые заголовочные файлы
  2. Объявляются переменные: buf - массив символов, ptr - указатель на строку, queue - очередь
  3. Создается новая очередь
  4. В цикле запрашивается ввод строки и добавляется в конец очереди
  5. В цикле пока очередь не пуста, извлекается первая строка, выводится на экран и освобождается память
  6. Освобождается память, выделенная под очередь
  7. Завершается программа

Оцени полезность:

12   голосов , оценка 4.25 из 5
Похожие ответы