2014-05-05 170 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