2014-05-05 4 views
-1

Все работает нормально, динамически создавая массив , но ядро ​​сбрасывается при попытке распечатать его назад. Удалось напечатать только последнюю строку, а затем ошибку сегментации.Выделение динамического 2D-массива

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

void init_array(void ***pt, int *ptlen) { 
    *pt=NULL; 
    *ptlen=0; 
} 

void trim_array(void ***pt, int *ptlen, int len) { 
    *pt=(void**)realloc(*pt, len*sizeof(void*)); 
    *ptlen=len; 
} 

void write_array(void ***pt, int *ptlen, int pos, void *v) { 
    if (pos >= *ptlen) 
     trim_array(pt, ptlen, pos+1); 

    *pt[pos]=v; 
} 

void *read_array(void ***pt, int *ptlen, int pos) { 
    return(*pt[pos]); 
} 

void destroy_array(void ***pt, int *ptlen) { 
    trim_array(pt, ptlen, 0); 
    *pt=NULL; 
} 

int main(int argc, char *argv[]) { 
    void **t; 
    int tlen; 

    void ***pt = &t; 
    int *ptlen = &tlen; 

    char s[256],*p; int i; 

    init_array(pt, ptlen); 

    i = 0; 
    do { 
     printf("give name:\n"); 
     scanf("%255s",s); 
     write_array(pt, ptlen, i, (void*)strdup(s)); 
     i++; 
    } while (strcmp(s,"end")); 

    for (--i; i>=0; i--) { 
     p = (char*)read_array(pt, ptlen, i); 
     printf("%s\n",p); 
     free(p); 
    } 

    destroy_array(pt, ptlen); 
    return(0); 
} 
+0

О, это неудачно. Может быть, мы сможем помочь. Пожалуйста, объясните, какую отладку вы уже сделали, чтобы мы не тратили время на то же самое. Какая строка претерпела изменения, значения индекса, подобные вещи. –

+0

1. печать динамических записей сразу после вызова write_array для каждого показала, что все «работает нормально» 2. попытка распечатать весь массив (последний цикл) привела к ошибке сегментации - была напечатана только запись LAST. – user3605146

+0

Можете ли вы по крайней мере, предоставить ввод, который вы используете? Зачем уходить с дороги, чтобы все угадали? –

ответ

1

Оператор [] имеет более высокий приоритет, чем оператор *. Вам нужно изменить:

*pt[pos] 

к:

(*pt)[pos] 

в обоих местах, где это происходит.

Эта ошибка является прямым результатом написания почти преднамеренно запутывающего кода с безоговорочной косвенностью. Вы бы сэкономили массу неприятностей и сделали намного проще, если бы вы собрали много всего этого в struct и создали для него некоторые правильные функции интерфейса.

Нечто подобное было бы немного лучшей форме (хотя "массив" на самом деле не великое имя для этой структуры данных):

main.c:

#define _POSIX_C_SOURCE 200809L 

#include <stdio.h> 
#include <stdlib.h> 
#include <stdbool.h> 
#include <string.h> 
#include "array.h" 

#define MAX_BUFFER_LEN 255 

int main(void) { 
    Array myarray = array_init(10, true); 

    /* Loop for input until user enters "end" */ 

    char buffer[MAX_BUFFER_LEN]; 
    while (true) { 
     printf("Give name: "); 
     fflush(stdout); 

     /* Get input and remove trailing '\n' if necessary */ 

     fgets(buffer, MAX_BUFFER_LEN, stdin); 
     size_t last = strlen(buffer) - 1; 
     if (buffer[last] == '\n') { 
      buffer[last] = '\0'; 
     } 

     /* Terminate loop on "end" without adding to array... */ 

     if (!strcmp(buffer, "end")) { 
      break; 
     } 

     /* ...or append input to array and continue loop */ 

     array_append(myarray, strdup(buffer)); 
    }; 

    /* Output contents of array */ 

    size_t n = array_size(myarray); 
    for (size_t i = 0; i < n; ++i) { 
     char * data = array_getdata(myarray, i); 
     printf("%zu: %s\n", i + 1, data); 
    } 

    /* Clean up and exit */ 

    array_destroy(myarray); 

    return EXIT_SUCCESS; 
} 

array.h:

#ifndef ARRAY_TYPE_H 
#define ARRAY_TYPE_H 

#include <stdbool.h> 

typedef struct array_type * Array; /* Opaque type for user */ 

Array array_init(const size_t capacity, const bool free_on_delete); 
void array_append(Array array, void * data); 
size_t array_size(const Array array); 
void * array_getdata(Array array, const size_t index); 
void array_deletetop(Array array); 
void array_destroy(Array array); 

#endif  /* ARRAY_TYPE_H */ 

array.c

#include <stdio.h> 
#include <stdlib.h> 
#include <stdbool.h> 
#include "array.h" 

/* Struct definition is visible only to implementation */ 

struct array_type { 
    void ** elements; 
    size_t capacity; 
    size_t top; 
    bool free_on_delete; 
}; 

/* Static functions used by the implementation */ 

static bool array_isfull(Array array) { 
    return (array->top + 1) == array->capacity; 
} 

static void array_resize(Array array, const size_t new_capacity) { 
    array->capacity = new_capacity; 
    array->elements = realloc(array->elements, 
           array->capacity * sizeof (*array->elements)); 
    if (array->elements == NULL) { 
     fputs("Error allocating memory.", stderr); 
     exit(EXIT_FAILURE); 
    } 
} 

/* Interface functions */ 

Array array_init(const size_t capacity, const bool free_on_delete) { 
    struct array_type * new_array = malloc(sizeof *new_array); 
    if (new_array == NULL) { 
     fputs("Error allocating memory.", stderr); 
     exit(EXIT_FAILURE); 
    } 

    new_array->elements = malloc(capacity * sizeof (*new_array->elements)); 
    if (new_array->elements == NULL) { 
     fputs("Error allocating memory.", stderr); 
     exit(EXIT_FAILURE); 
    } 

    new_array->capacity = capacity; 
    new_array->top = 0; 
    new_array->free_on_delete = free_on_delete; 

    return new_array; 
} 

void array_append(Array array, void * data) { 
    if (array_isfull(array)) { 
     array_resize(array, array->capacity * 2); 
    } 
    array->elements[array->top++] = data; 
} 

size_t array_size(const Array array) { 
    return array->top; 
} 

void * array_getdata(Array array, const size_t index) { 
    return array->elements[index]; 
} 

void array_deletetop(Array array) { 
    if (array->free_on_delete) { 
     free(array->elements[array->top - 1]); 
    } 
    array->elements[--array->top] = NULL; 
} 

void array_destroy(Array array) { 
    while (array->top > 0) { 
     array_deletetop(array); 
    } 
    free(array->elements); 
    free(array); 
} 

Пример вывода:

[email protected]:~/src/c/scratch/array$ ./array 
Give name: Dave Dee 
Give name: Dozy 
Give name: Beaky 
Give name: Mick 
Give name: Titch 
Give name: end 
1: Dave Dee 
2: Dozy 
3: Beaky 
4: Mick 
5: Titch 
[email protected]:~/src/c/scratch/array$ 
+0

спасибо мат. он работает .. я также проверю ваш список .. – user3605146

Смежные вопросы