我正在尝试使用数组在C中实现堆栈。我想要一个整数数组,每次我尝试推送一个int我想分配一些新的内存。但是我对malloc()
的理解是它返回一个指向它在某处分配的内存的指针,如果我有一个int指针数组就没问题,但我没有。这是我分配新内存的地方,我收到警告:
int stack[] = {1}; // stack is allocated like this
stack[lasti + 1] = malloc(sizeof(int)); // assignment makes integer from pointer without a cast
是否可以使用动态分配的非指针数组实现堆栈?或者malloc()
是否仅仅使用指针数组?
malloc(sizeof(int) * maxSize)
。这将在某处产生大量内存。我不能做的是请求malloc在该块的末尾给我另一块内存,但我可以扩展该块。如果我使用链表实现堆栈,那么malloc放置新空间并不重要。我想我正在混合一些东西。
接下来的问题 - 如果使用数组实现堆栈,我是否必须指定堆栈的最大大小?
答案 0 :(得分:1)
SELECT *
FROM @T
WHERE ID = @YourID AND Name = @YourName
UNION ALL
SELECT *
FROM @T
WHERE ID = @YourID;
返回的内存可用于存储特定大小的malloc()
数组。实现数据结构的一种方法是使用int
分配固定大小的int
数组。然后,您可以将元素插入到数组中,直到达到其最大大小。此时,您可以malloc()
(请参阅手册页以获取更多详细信息)来调整先前分配的块的大小以获得更多内存(您可以将先前大小的par示例加倍)。或者另一种技术是使用多级堆栈,这意味着每当前一个堆栈空间不足时,就会向堆栈库添加新的堆栈帧。避免realloc()
的另一种可能方法(如果处理大型内存块,则可能会失败)是将前一个堆栈帧交换到磁盘,只要它是满的。然后使用相同的框架插入新值。
realloc()
堆栈的实现:
realloc()
在调用#define SCALE_FACTOR 2 /* Double stack size at each new realloc */
typedef struct stack {
int *array;
int stack_size; /* Maximum number of elements */
int stack_pointer;
} Stack;
int insert(Stack *ptr, int value)
{
if(ptr->stack_pointer >= ptr->stack_size) {
int realloc_size = ptr->stack_size * SCALE_FACTOR;
int *new_array = realloc(ptr->array, realloc_size * sizeof(int));
if(!new_array)
return -1; /* Resizing failed */
ptr->array = new_array;
ptr->stack_size = realloc_size;
}
ptr->array[ptr->stack_pointer++] = value;
return ptr->stack_pointer;
}
之前,您必须初始化堆栈结构
我在ideone.com
(永久保存文件)上编写了一个演示,演示了一个完整的堆栈实现,其中插入了100个元素,初始大小为25个元素。
有些人建议每次新插入时拨打insert()
。这种方法非常糟糕,因为它会导致可怕的性能下降(realloc()是一个重载函数),尤其是当插入过程在一个单位时间内发生很多次时(插入开销)。
答案 1 :(得分:1)
你完全误解了malloc()
的作用 - 它返回一个指向内存块的指针;你可以解释你想要的内存块 - 它不是指针数组 - 指针就是你引用数组的方式。
要使用连续的内存块动态实现堆栈,您需要使用realloc()
调整分配大小;然而,这可能是极其低效的,因为在大多数情况下,现有的分配不能简单地扩展,并且需要创建新的更大的分配,而不是在删除先前的分配之前复制到它的现有分配的所有内容。一种解决方案是在" chunks"中扩展堆栈,其中块大小是当前容量的一部分,因此重新分配的数量适应于使用。
#define INITIAL_STACK_SIZE 128
#define STACK_GROWTH_FACTOR 8
static int stack_size = INITIAL_STACK_SIZE ;
static int* stack = 0 ;
static int stack_index = 0 ;
void create()
{
stack_size = STACK_GROWTH_FACTOR ;
stack = calloc( stack_size, sizeof(int) ) ;
}
void destroy()
{
free( stack ) ;
stack = 0 ;
stack_index = 0 ;
stack_size = 0 ;
}
void push( int i )
{
if( stack != 0 )
{
if( stack_index >= stack_size )
{
stack_size += stack_size / STACK_GROWTH_FACTOR ;
stack = realloc( stack, stack_size * sizeof(int) ) ;
}
stack[stack_index] = i ;
stack_index++ ;
}
}
int pop()
{
int i = 0 ;
if( stack != 0 )
{
i = stack[stack_index] ;
stack_index-- ;
}
return i ;
}
当pop()
低于stack_index
的某个比例时,上述解决方案还可以适应 例如{1}}并且可能还允许多个堆栈。可以包含对stack_size
/ calloc()
来电的一些安全检查,但为了清楚起见,我省略了。
答案 2 :(得分:0)
当你在main函数中声明小数组时,它会进入stack memory
。动态分配的内存进入堆,您可以通过指针分配内存。首先你声明pointer to int
并通过malloc
分配小内存,当需要时你可以通过realloc()
重新分配内存。就像这样
int* stack=malloc(sizeof(int));
stack=realloc(stack,(size+1)*sizeof(int)); //size is the size of stack
始终记得检查错误。
答案 3 :(得分:0)
更好地理解指针是如何工作的,让我们看看并比较两个声明:
int array[10];//note that we know the size of the array
第二个使用指针:
int *array = NULL;
指针“array”将地址存储在int数组的第一个值的内存中。 我们必须“手动”在内存中分配一些空间,因此我们的进程可以在这个内存区域中进行读写。 为此,让我们看看这段代码:
#include <stdlib.h>
#include <stdio.h>
int *dynamic_int_array_allocation(int *array, int size){
if(size == 0){
// if the size specified by the size variable is 0 then allocate
// memory for one int, the size of this int in the memory is 2 or 4 bytes
// it depend on your platform
// if you want to know how many bytes their was used, use the following:
// printf("The size of int in this platform is %lu\n", sizeof(int));
array = (int*)malloc(sizeof(int));
}
else if(size != 0){
// else if the size specified by the size variable is not 0
// then we have to realloc our integer array, to do so
// we declare a temporary integer pointer here:
int *t1;
// we reallocate our previous pointer with the size variable
t1 = realloc(array, size * sizeof(int));
// if the request failed (realloc return null) we free our array
// if the request succeed we assign to our array pointer the address of
// the new area of memory returned by the realloc function
if(array == NULL)
free(array);
else
array = t1;
}
return array; // return the address of the array
}
//to test our function:
int main(int argc, char const *argv[]) {
// declaration of our array
int *my_integer_array = NULL;
// allocate a new area of memory to our array
my_integer_array = dynamic_int_array_allocation(my_integer_array, 0);
printf("This is the first address of our pointer is: %p\n", my_integer_array);
// to test our function, we use here a for loop
for (int i = 0; i < 10; i++) {
// this realloc our tab at each iteraction
// we use i+1 because "i" was at 0 and we want
// the function to reallocate our array with 2 boxes at the beginning of this loop
// at the end of the loop i will be 9 and we will have 10 boxes in our array
// wich is ok
my_integer_array = dynamic_int_array_allocation(my_integer_array, i+1);
// we fill the boxes of our array with integers
my_integer_array[i] = i;
printf("The new address of our pointer is: %p\n", my_integer_array);
}
// What is in our array:
for (int i = 0; i < 10; ++i)
{
printf("array[%d] = %d\n",i, my_integer_array[i] );
}
//don't forget to free the zone of allocated memory
free(my_integer_array);
return 0;
}