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;
}