Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 双动态堆栈阵列_C_Arrays_Dynamic_Stack_Realloc - Fatal编程技术网

C 双动态堆栈阵列

C 双动态堆栈阵列,c,arrays,dynamic,stack,realloc,C,Arrays,Dynamic,Stack,Realloc,我有一个数组用于表示通用堆栈 struct Stack { int size; int type; int capacity; void **data; // An array of generic data. }; Stack *new_stack(int type) { Stack *tmp = malloc(sizeof(Stack)); assert(tmp != NULL); tmp->size = 0; tmp-

我有一个数组用于表示通用堆栈

struct Stack {
    int size;
    int type;
    int capacity;
    void **data; // An array of generic data.
};

Stack *new_stack(int type) {
    Stack *tmp = malloc(sizeof(Stack));
    assert(tmp != NULL);
    tmp->size = 0;
    tmp->type = type;
    tmp->capacity = DEFAULT_CAPACITY;
    tmp->data = calloc(tmp->capacity, type);
    assert(tmp->data != NULL);
    return tmp;
}
这是在保留数据的同时将数组加倍的正确方法吗

void realloc_stack(Stack *s) {
    int old_capacity = s->capacity;
    s->capacity *= 2;
    s->data = realloc(s->data, s->capacity);
    memset(s->data + old_capacity, 0, old_capacity);
    assert(s->data != NULL);
}
但是,当我尝试从push_堆栈调用此函数时,如下所示:

void push_stack (Stack *s, void *data) {
    if (full_stack(s)) realloc_stack(s);
    s->data[s->size++] = data;
}
我遇到了这个问题:基本上是一堆实际数字应该是零的地方

int main() {

    Stack *intStack = new_stack(sizeof(int));

    for (int i = 0; i < 15; ++i) {
        push_stack(intStack, (void*)i);
    }
}

进一步阐述Paul Roub在上述评论中所说的内容:

您正在调用memset->data+old_capacity,0,old_capacity;您的目的是用0写入数组的后半部分;然而,事实并非如此。根据,memset将ptr指向的内存块的第一个num字节设置为指定值。您试图用32位而不是8位的整数填充数组。因此,您可能应该将调用调整为:

memset(s->data + (old_capacity * s->type), 0, old_capacity * s->type);

这应该可以解决你的问题。祝你好运

Stack.data的类型是什么?请记住,s->data+旧容量将基于该大小,而不是sizeofchar。您在这里面临缓冲区溢出的风险。tmp->data=calloctmp->capacity,type;s->data=reallocs->data,s->capacity;:这在容量的意义上是不一致的。@Raymond您有一个未显示的结构类型堆栈。它有一个数据成员,其类型和大小我们看不到。s->data[s->size++]=data;:类型和大小不一致,所以应该是:s->data=reallocs->data,s->type*s->capacity;对吗?这不起作用,但它确实稍微改变了输出。打印堆栈:14 13 12 11 10 0 0 0 0 0 0 9 8 7 6 1 0哦,哇,我这一头全是大脑放屁。很抱歉。我认为在这两种情况下都应该是s->type而不是s->type/4。如果这不起作用,尝试将其保留为起始位置的s->data+旧容量。我自己尝试这个,但是我在这个计算机上没有C++编译器。你也可以把ReLoC调用改成RealOrth->数据,S- >容量*s>类型;出于同样的原因。嗨,蓝精灵,这起作用了。你能解释一下为什么我们需要char*cast吗?谢谢你的帮助@雷蒙德;指向void*的1指针算法是未定义的行为。2基于void*大小的内存位置不代表所需内存的位置。它应该基于s->type的大小。e、 g int*p=0;p+1意味着0+sizeoffintit可以正确计算并强制转换为char*,因为sizeofchar为1是有保证的。因此,它等于指定的位置。注意:GCC中的void*计算作为扩展规范是允许的。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#define DEFAULT_CAPACITY 8

typedef struct Stack {
    int size;    //number of element
    size_t type; //size of type, there are no problems with int
    int capacity;//max number of element
    void *data;  //memory of type * capacity
} Stack;

Stack *new_stack(size_t type) {
    Stack *tmp = malloc(sizeof(Stack));
    assert(tmp != NULL);
    tmp->size = 0;
    tmp->type = type;
    tmp->capacity = DEFAULT_CAPACITY;
    tmp->data = calloc(tmp->capacity, type);
    assert(tmp->data != NULL);
    return tmp;
}

void realloc_stack(Stack *s) {
    int old_capacity = s->capacity * s->type;
    s->capacity *= 2;
    s->data = realloc(s->data, s->capacity * s->type);
    assert(s->data != NULL);
    memset((char*)s->data + old_capacity, 0, old_capacity);
}

static inline int full_stack(Stack *s){//Deleting a "static inline" if you are open to the public as an interface
    return s->capacity == s->size;
}

void push_stack (Stack *s, void *data) {
    if (full_stack(s)) realloc_stack(s);
    memcpy((char*)s->data + s->type * s->size++, data, s->type);
}

void printIntObjectDump(Stack *s){
    int i, *p = s->data;
    for(i=0;i<s->capacity;++i){
        printf("%d\n", p[i]);
    }
}

int main() {
    Stack *intStack = new_stack(sizeof(int));

    for (int i = 0; i < 15; ++i) {
        push_stack(intStack, &i);
    }
    printIntObjectDump(intStack);
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#define DEFAULT_CAPACITY 8

typedef struct Stack {
    int size;    //number of element
    size_t type; //size of type, there are no problems with int
    int capacity;//max number of element
    void *data;  //memory of type * capacity
} Stack;

Stack *new_stack(size_t type) {
    Stack *tmp = malloc(sizeof(Stack));
    assert(tmp != NULL);
    tmp->size = 0;
    tmp->type = type;
    tmp->capacity = DEFAULT_CAPACITY;
    tmp->data = calloc(tmp->capacity, type);
    assert(tmp->data != NULL);
    return tmp;
}

void realloc_stack(Stack *s) {
    int old_capacity = s->capacity * s->type;
    s->capacity *= 2;
    s->data = realloc(s->data, s->capacity * s->type);
    assert(s->data != NULL);
    memset((char*)s->data + old_capacity, 0, old_capacity);
}

static inline int full_stack(Stack *s){//Deleting a "static inline" if you are open to the public as an interface
    return s->capacity == s->size;
}

void push_stack (Stack *s, void *data) {
    if (full_stack(s)) realloc_stack(s);
    memcpy((char*)s->data + s->type * s->size++, data, s->type);
}

void printIntObjectDump(Stack *s){
    int i, *p = s->data;
    for(i=0;i<s->capacity;++i){
        printf("%d\n", p[i]);
    }
}

int main() {
    Stack *intStack = new_stack(sizeof(int));

    for (int i = 0; i < 15; ++i) {
        push_stack(intStack, &i);
    }
    printIntObjectDump(intStack);
    return 0;
}