2014-05-05 172 views
-1

在動態創建數組 時,似乎一切正常,但在嘗試向後打印時核心轉儲。 它設法只打印最後一個字符串,然後分段錯誤。分配動態二維數組

#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.試圖打印整個數組(最後一個for循環)導致分段錯誤 - 只打印最後一個條目.. – 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